#include "sal.h"
#include "ctc_cli.h"
#include "usw/include/drv_enum.h"
#include "drv_api.h"
#include "usw/include/drv_common.h"
#include "usw/include/drv_chip_ctrl.h"
#include "ctc_dkit.h"
#include "ctc_dkit_common.h"
#include "ctc_usw_dkit_misc.h"
#include "ctc_usw_dkit.h"
#include "ctc_usw_dkit_dump_cfg.h"
#include "ctc_at_dkit_serdes_reg.h"
#include "ctc_at_dkit_serdes.h"

int32 
_ctc_at_dkit_convert_twos_complement_to_i32(uint32 tc, uint16 tcBits);
uint32 
_ctc_at_dkit_convert_graycode_to_u32(uint32 graycode);
uint8 
_ctc_at_dkit_get_serdes_modulation_mode(ctc_at_dkit_serdes_dev_t* p_dev);
uint8 
_ctc_at_dkit_get_serdes_type(uint8 lchip, uint16 serdes_id);
uint8 
_ctc_at_dkit_get_chip_type(uint8 lchip);
int32
_ctc_at_dkit_eom_get_eye_data(ctc_at_dkit_serdes_dev_t* p_dev, uint8 tmb, uint32 min_samples, uint32 ber_thrd, uint8 eomStatsMode, void* p_eye_data);
void
_ctc_at_dkit_serdes_dev(uint8 lchip, uint16 serdes_id, ctc_at_dkit_serdes_dev_t* p_dev);
void
_ctc_at_dkit_misc_serdes_get_rx_train_stat(ctc_at_dkit_serdes_dev_t* p_dev, uint16* p_en, uint16* p_co, uint16* p_fa);
void
_ctc_at_dkit_misc_serdes_get_tx_train_stat(ctc_at_dkit_serdes_dev_t* p_dev, uint16* p_en, uint16* p_co, uint16* p_fa);
void _ctc_at_dkit_set_data_width(ctc_at_dkit_serdes_dev_t* p_dev, uint16 txWidth, uint16 rxWidth);

#if defined(_SAL_LINUX_KM)
#define UINT64_PRINT_FMT_LU
#endif

#define CTC_DKIT_AT_MCMAC_NUM_PER_CORE 20   
#define CTC_DKIT_AT_SERDES_NUM_PER_MCMAC 8
#define CTC_DKIT_AT_MAC_GROUP_NUM_HALF_CORE 10
#define CTC_DKIT_AT_NW_SERDES_NUM_PER_CORE 160
#define CTC_DKIT_AT_CORE_NUM               2
#define CTC_DKIT_AT_NW_SERDES_NUM CTC_DKIT_AT_NW_SERDES_NUM_PER_CORE*CTC_DKIT_AT_CORE_NUM
#define CTC_DKIT_AT_IS_CPUMAC_SERDES(serdes_id) ((serdes_id) < CTC_DKIT_AT_NW_SERDES_NUM ? FALSE : TRUE)
#define CTC_DKIT_AT_MAX_MAC_NUM_PER_CORE 160
#define CTC_DKIT_AT_LANE_NUM_PER_HSS 4
#define CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(serdes_id) (CTC_DKIT_AT_IS_CPUMAC_SERDES(serdes_id) ? 40 : (serdes_id % CTC_DKIT_AT_NW_SERDES_NUM_PER_CORE / CTC_DKIT_AT_LANE_NUM_PER_HSS))
#define CTC_DKIT_AT_SERDES_GET_LANE(serdes_id) (serdes_id % CTC_DKIT_AT_LANE_NUM_PER_HSS)
#define CTC_DKIT_AT_GET_HSS_ID_BY_SERDES(serdes_id) ((serdes_id) / CTC_DKIT_AT_LANE_NUM_PER_HSS)
#define CTC_DKIT_AT_GET_CORE_ID_BY_LOGIC_SERDES(logic_serdes) (CTC_DKIT_AT_IS_CPUMAC_SERDES(logic_serdes) ? 0 : ((logic_serdes) / CTC_DKIT_AT_MAX_MAC_NUM_PER_CORE))
#define CTC_DKIT_AT_112G_SERDES_FIRST 16
#define CTC_DKIT_AT_112G_SERDES_LAST  143
#define CTC_DKIT_AT_IS_SERDES_SPEED_PAM4(serdes_speed)   ((serdes_speed == DKIT_SERDES_SPEED_51_5625G || serdes_speed == DKIT_SERDES_SPEED_53_125G  ||\
                                                  serdes_speed == DKIT_SERDES_SPEED_56_25G   || serdes_speed == DKIT_SERDES_SPEED_106_25G  ||\
                                                  serdes_speed == DKIT_SERDES_SPEED_112_5G   || serdes_speed == DKIT_SERDES_SPEED_56_25G   ||\
                                                  serdes_speed == DKIT_SERDES_SPEED_42_5G) ? TRUE : FALSE)

#define DKIT_SERDES_ID_MAX 324
#define DKITS_SERDES_ID_CHECK(LCHIP,ID)

#define CTC_DKIT_AT_MCU_NUM_PER_CORE                  21
#define CTC_DKIT_AT_MCU_MAX_GRAND_ID                  7
#define CTC_DKIT_AT_MCU_MAX_GRAND_BIT_ID              31
#define CTC_DKIT_HW_LOCK_SERDES_REG_IO_GRANT_ID       0
#define CTC_DKIT_HW_LOCK_SERDES_REG_IO_0_BIT_OF_GRANT 1
#define CTC_DKIT_HW_LOCK_SERDES_REG_IO_1_BIT_OF_GRANT 2
#define CTC_DKIT_AT_MCU_ID_TO_CORE_ID(core_id, mcu_id)   (core_id = (mcu_id / CTC_DKIT_AT_MCU_NUM_PER_CORE))
#define CTC_DKIT_AT_MCU_ID_PER_CORE(mcu_id)              (mcu_id % CTC_DKIT_AT_MCU_NUM_PER_CORE)
#define CTC_DKIT_SERDES_REG_IO_HW_LOCK(lchip, mcu_id, hss_grp)   _ctc_at_dkit_mcu_hw_lock(lchip, mcu_id, CTC_DKIT_HW_LOCK_SERDES_REG_IO_GRANT_ID, \
                                                                               ((hss_grp == 0) ? CTC_DKIT_HW_LOCK_SERDES_REG_IO_0_BIT_OF_GRANT : CTC_DKIT_HW_LOCK_SERDES_REG_IO_1_BIT_OF_GRANT))
#define CTC_DKIT_SERDES_REG_IO_HW_UNLOCK(lchip, mcu_id, hss_grp) _ctc_at_dkit_mcu_hw_unlock(lchip, mcu_id, CTC_DKIT_HW_LOCK_SERDES_REG_IO_GRANT_ID, \
                                                                               ((hss_grp == 0) ? CTC_DKIT_HW_LOCK_SERDES_REG_IO_0_BIT_OF_GRANT : CTC_DKIT_HW_LOCK_SERDES_REG_IO_1_BIT_OF_GRANT))

#define CTC_DKIT_IS_BIT_SET(flag, bit)   (((flag) & (1 << (bit))) ? 1 : 0)
#define CTC_DKIT_BIT_SET(flag, bit)      ((flag) |= (1 << (bit)))
#define CTC_DKIT_BIT_UNSET(flag, bit)    ((flag) &= (~(1 << (bit))))

extern ctc_dkit_master_t* g_usw_dkit_master[CTC_DKITS_MAX_LOCAL_CHIP_NUM];

struct ctc_dkit_at_serdes_ctl_loopback_s
{
    uint16 serdes_id;
    uint8 oper;
    uint8 mode;
};
typedef struct ctc_dkit_at_serdes_ctl_loopback_s ctc_dkit_at_serdes_ctl_loopback_t;

struct ctc_dkit_at_serdes_ctl_eye_s
{
    uint16 serdes_id;
    uint8 eye_type;
    uint32 read_times;
};
typedef struct ctc_dkit_at_serdes_ctl_eye_s ctc_dkit_at_serdes_ctl_eye_t;

struct ctc_dkit_at_serdes_ctl_ffe_s
{
    uint16 serdes_id;
    uint16 dest_serdes_id;
    uint8 prbs_pattern;
    uint32 threshold;//coefficient sum threshold
    uint32 delay;
    char *str;
    ctc_dkit_serdes_para_ffe_t *ffe;
};
typedef struct ctc_dkit_at_serdes_ctl_ffe_s ctc_dkit_at_serdes_ctl_ffe_t;

struct ctc_dkit_at_serdes_ctl_pol_check_s
{
    uint16 serdes_id;
    uint8 paired_serdes_id;
};
typedef struct ctc_dkit_at_serdes_ctl_pol_check_s ctc_dkit_at_serdes_ctl_pol_check_t;


struct ctc_dkit_at_serdes_ctl_dfe_s
{
    uint16 serdes_id;
    uint8 oper;
    uint8 delta;
    int8 taps[5];
    int32 taps_pam4[5];
};
typedef struct ctc_dkit_at_serdes_ctl_dfe_s ctc_dkit_at_serdes_ctl_dfe_t;

struct ctc_dkit_at_serdes_ctl_fw_s
{
    uint16 serdes_id;
    uint8 oper;
};
typedef struct ctc_dkit_at_serdes_ctl_fw_s ctc_dkit_at_serdes_ctl_fw_t;

struct ctc_dkit_at_serdes_ctl_bathtub_s
{
    uint16 serdes_id;
    uint8 oper;
    uint8 depth;
};
typedef struct ctc_dkit_at_serdes_ctl_bathtub_s ctc_dkit_at_serdes_ctl_bathtub_t;



struct ctc_dkit_at_serdes_ber_mon_s
{
    uint8  lchip;
    uint8  is_run;
    uint8  opr_lock[DKIT_SERDES_ID_MAX];
    uint8  is_mon[DKIT_SERDES_ID_MAX];
    uint64 tot_cnt[DKIT_SERDES_ID_MAX];
    uint64 err_cnt[DKIT_SERDES_ID_MAX];
};
typedef struct ctc_dkit_at_serdes_ber_mon_s ctc_dkit_at_serdes_ber_mon_t;

struct ctc_dkit_at_serdes_ctl_prbs_s
{
    uint8  lchip;
    uint16 serdes_id;
    uint8  oper; /*ctc_dkit_serdes_ctl_t*/
    uint8  pattern;
    uint8  is_keep;
    uint32 timer_ms;
    uint64 totcnt;
    uint64 errcnt;
    char *str;
};
typedef struct ctc_dkit_at_serdes_ctl_prbs_s ctc_dkit_at_serdes_ctl_prbs_t;

int32
_ctc_at_dkit_serdes_serdes_to_psd(uint8 lchip, uint16 serdes_id, uint16* psd)
{
    uint8 mac_group_id = 0;
    DKITS_PTR_VALID_CHECK(psd);

    if (DKIT_AT_USELESS_ID16 == serdes_id)
    {
        *psd = DKIT_AT_USELESS_ID16;
    }

    mac_group_id = (serdes_id / CTC_DKIT_AT_SERDES_NUM_PER_MCMAC) % CTC_DKIT_AT_MCMAC_NUM_PER_CORE;
    if (mac_group_id < CTC_DKIT_AT_MAC_GROUP_NUM_HALF_CORE)
    {
        *psd = serdes_id;
    }
    else
    {
        *psd = (serdes_id % CTC_DKIT_AT_SERDES_NUM_PER_MCMAC < CTC_DKIT_AT_LANE_NUM_PER_HSS) ?
            (serdes_id + CTC_DKIT_AT_LANE_NUM_PER_HSS) : (serdes_id - CTC_DKIT_AT_LANE_NUM_PER_HSS);
    }

    return CLI_SUCCESS;
}

int32
_ctc_at_dkit_serdes_psd_to_serdes(uint8 lchip, uint16 psd, uint16* serdes_id)
{
    uint8 mac_group_id = 0;
    DKITS_PTR_VALID_CHECK(serdes_id);

    if (DKIT_AT_USELESS_ID16 == psd)
    {
        *serdes_id = DKIT_AT_USELESS_ID16;
    }

    mac_group_id = (psd / CTC_DKIT_AT_SERDES_NUM_PER_MCMAC) % CTC_DKIT_AT_MCMAC_NUM_PER_CORE;
    if (mac_group_id < CTC_DKIT_AT_MAC_GROUP_NUM_HALF_CORE)
    {
        *serdes_id = psd;
    }
    else
    {
        *serdes_id = (psd % CTC_DKIT_AT_SERDES_NUM_PER_MCMAC < CTC_DKIT_AT_LANE_NUM_PER_HSS) ?
            (psd + CTC_DKIT_AT_LANE_NUM_PER_HSS) : (psd - CTC_DKIT_AT_LANE_NUM_PER_HSS);
    }

    return CLI_SUCCESS;
}

/*
 * grand_id : 0 - 7
 * bit      : 0 - 31
 */
static void
_ctc_at_dkit_mcu_hw_lock(uint8 lchip, uint32 mcu_id, uint8 grand_id, uint8 bit)
{
    uint8  core_id    = 0;
    uint32 value      = 0;
    uint32 cmd        = 0;
    uint32 entry_id   = 0;
    uint32 inst_id    = CTC_DKIT_AT_MCU_ID_PER_CORE(mcu_id);
    uint32 ext_tbl_id = McpuGrant0ExtCtl_t + grand_id;
    uint32 index      = DRV_INS(inst_id, entry_id);

    /* param check */
    if ((grand_id > CTC_DKIT_AT_MCU_MAX_GRAND_ID) || (bit > CTC_DKIT_AT_MCU_MAX_GRAND_BIT_ID))
    {
        return;
    }

    /* Get Core ID */
    CTC_DKIT_AT_MCU_ID_TO_CORE_ID(core_id, mcu_id);

    /* Get Lock */
    while(1)
    {
        cmd  = DRV_IOR(ext_tbl_id, DRV_ENTRY_FLAG);
        (void)DKIT_DRV_IOCTL_CORE(lchip, index, core_id, cmd, &value);
        
        CTC_DKIT_BIT_SET(value, bit);

        cmd  = DRV_IOW(ext_tbl_id, DRV_ENTRY_FLAG);
        (void)DKIT_DRV_IOCTL_CORE(lchip, index, core_id, cmd, &value);

        cmd  = DRV_IOR(ext_tbl_id, DRV_ENTRY_FLAG);
        (void)DKIT_DRV_IOCTL_CORE(lchip, index, core_id, cmd, &value);

        if (CTC_DKIT_IS_BIT_SET(value, bit))
        {
            break;
        }
    }

    return;
}

/*
 * grand_id : 0 - 7
 * bit      : 0 - 31
 */
static void
_ctc_at_dkit_mcu_hw_unlock(uint8 lchip, uint32 mcu_id, uint8 grand_id, uint32 bit)
{
    uint8  core_id    = 0;
    uint32 val_write  = 0;
    uint32 cmd        = 0;
    uint32 entry_id   = 0;
    uint32 inst_id    = CTC_DKIT_AT_MCU_ID_PER_CORE(mcu_id);
    uint32 ext_tbl_id = McpuGrant0ExtCtl_t + grand_id;
    uint32 index      = DRV_INS(inst_id, entry_id);
    
    /* param check */
    if ((grand_id > CTC_DKIT_AT_MCU_MAX_GRAND_ID) || (bit > CTC_DKIT_AT_MCU_MAX_GRAND_BIT_ID))
    {
        return;
    }

    /* Get Core ID */
    CTC_DKIT_AT_MCU_ID_TO_CORE_ID(core_id, mcu_id);

    /* unlock */
    cmd  = DRV_IOR(ext_tbl_id, DRV_ENTRY_FLAG);
    (void)DKIT_DRV_IOCTL_CORE(lchip, index, core_id, cmd, &val_write);
        
    CTC_DKIT_BIT_UNSET(val_write, bit);
    
    cmd  = DRV_IOW(ext_tbl_id, DRV_ENTRY_FLAG);
    (void)DKIT_DRV_IOCTL_CORE(lchip, index, core_id, cmd, &val_write);
    
    return;
}
 


#define __CTC_AT_DKIT_APB_REG__ 

void 
_ctc_at_dkit_serdes_read_reg(ctc_at_dkit_serdes_dev_t* p_dev, uint32 reg, uint32* p_value)
{
    uint32 core_id = CTC_DKIT_AT_GET_CORE_ID_BY_LOGIC_SERDES(p_dev->serdes_id);
    uint32 grp_id = CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    grp_id = (0x000000ff & grp_id) | (0x00400000 << core_id);
    
    drv_chip_read_hss(p_dev->lchip, grp_id, reg, p_value);
   
    CTC_DKIT_PRINT_DEBUG("read chip id:%d, hss id:%d, addr: 0x%04x, value: 0x%04x\n", p_dev->lchip, grp_id, reg, *p_value);
}

void 
_ctc_at_dkit_serdes_write_reg(ctc_at_dkit_serdes_dev_t* p_dev, uint32 reg, uint32 value)
{
    uint32 core_id = CTC_DKIT_AT_GET_CORE_ID_BY_LOGIC_SERDES(p_dev->serdes_id);
    uint32 grp_id = CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    grp_id = (0x000000ff & grp_id) | (0x00400000 << core_id);
    
    drv_chip_write_hss(p_dev->lchip, grp_id, reg, &value);
    
    CTC_DKIT_PRINT_DEBUG("write chip id:%d, hss id:%d, addr: 0x%04x, value: 0x%04x\n", p_dev->lchip, grp_id, reg, value);
}

void _ctc_at_dkit_serdes_read_reg_lane(ctc_at_dkit_serdes_dev_t* p_dev, uint32 reg, 
                                                uint8 reg_type, uint32* p_data)
{
    _ctc_at_dkit_serdes_field_t* p_lane_sel = NULL;
    uint32 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    uint32 reg_val = 0;
    /* Lane switching is necessary for register adresses from 0 ~ 0x7FFC */
    if((0x8000 > reg) && (CTC_AT_DKIT_SERDES_REG_LANE == reg_type))
    {
        p_lane_sel = (CTC_AT_DKIT_SERDES_56G == p_dev->type) ? 
            DKIT_REG_STR(F_DKIT_AT56G_LANE_SEL) : DKIT_REG_STR(F_DKIT_AT112G_LANE_SEL);
        (void)(_ctc_at_dkit_serdes_read_reg(p_dev, p_lane_sel->reg, &reg_val));
        if(lane != (reg_val & (~(p_lane_sel->retain_mask))) >> p_lane_sel->lo_bit)
        {
            reg_val = (reg_val & p_lane_sel->retain_mask) | ((lane << p_lane_sel->lo_bit) & p_lane_sel->mask);
            (void)(_ctc_at_dkit_serdes_write_reg(p_dev, p_lane_sel->reg, reg_val));
        }
    }
    (void)(_ctc_at_dkit_serdes_read_reg(p_dev, reg, p_data));
    
}

void _ctc_at_dkit_serdes_write_reg_lane(ctc_at_dkit_serdes_dev_t* p_dev, uint32 reg, 
                                                uint8 reg_type, uint32 data)
{
    _ctc_at_dkit_serdes_field_t* p_lane_sel = NULL;
    uint32 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    uint32 reg_val = 0;
    /* Lane switching is necessary for register adresses from 0 ~ 0x7FFC */
    if((0x8000 > reg) && (CTC_AT_DKIT_SERDES_REG_LANE == reg_type))
    {
        p_lane_sel = (CTC_AT_DKIT_SERDES_56G == p_dev->type) ? 
            DKIT_REG_STR(F_DKIT_AT56G_LANE_SEL) : DKIT_REG_STR(F_DKIT_AT112G_LANE_SEL);
        (void)(_ctc_at_dkit_serdes_read_reg(p_dev, p_lane_sel->reg, &reg_val));
        if(lane != (reg_val & (~(p_lane_sel->retain_mask))) >> p_lane_sel->lo_bit)
        {
            reg_val = (reg_val & p_lane_sel->retain_mask) | ((lane << p_lane_sel->lo_bit) & p_lane_sel->mask);
            (void)(_ctc_at_dkit_serdes_write_reg(p_dev, p_lane_sel->reg, reg_val));
        }
    }
    (void)(_ctc_at_dkit_serdes_write_reg(p_dev, reg, data));
    
}

void _ctc_at_dkit_serdes_read_reg_field(ctc_at_dkit_serdes_dev_t* p_dev, _ctc_at_dkit_serdes_field_t* p_field, 
                                               uint8 reg_type, uint32* p_data)
{
    uint8  grp_id  = 0;
    uint8  core    = 0;
    uint8  hss_grp = 0;
    uint32 mcu_id  = 0;
    uint32 reg_val = 0;

    grp_id  = CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    core    = CTC_DKIT_AT_GET_CORE_ID_BY_LOGIC_SERDES(p_dev->serdes_id);
    mcu_id  = (core*CTC_DKIT_AT_MCU_NUM_PER_CORE) + (grp_id/2);
    hss_grp = grp_id%2;

    CTC_DKIT_SERDES_REG_IO_HW_LOCK(p_dev->lchip, mcu_id, hss_grp);
    (void)(_ctc_at_dkit_serdes_read_reg_lane(p_dev, p_field->reg, reg_type, &reg_val));
    *p_data = (uint32)((reg_val & p_field->mask) >> p_field->lo_bit);
    CTC_DKIT_SERDES_REG_IO_HW_UNLOCK(p_dev->lchip, mcu_id, hss_grp);
}

void _ctc_at_dkit_serdes_write_reg_field(ctc_at_dkit_serdes_dev_t* p_dev, _ctc_at_dkit_serdes_field_t* p_field, 
                                                uint8 reg_type, uint32 data)
{
    uint8  grp_id  = 0;
    uint8  core    = 0;
    uint8  hss_grp = 0;
    uint32 mcu_id  = 0;
    uint32 reg_val = 0;

    grp_id  = CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    core    = CTC_DKIT_AT_GET_CORE_ID_BY_LOGIC_SERDES(p_dev->serdes_id);
    mcu_id  = (core*CTC_DKIT_AT_MCU_NUM_PER_CORE) + (grp_id/2);
    hss_grp = grp_id%2;

    CTC_DKIT_SERDES_REG_IO_HW_LOCK(p_dev->lchip, mcu_id, hss_grp);
    (void)(_ctc_at_dkit_serdes_read_reg_lane(p_dev, p_field->reg, reg_type, &reg_val));
    reg_val = (reg_val & p_field->retain_mask) | ((data << p_field->lo_bit) & p_field->mask);
    (void)(_ctc_at_dkit_serdes_write_reg_lane(p_dev, p_field->reg, reg_type, reg_val));
    CTC_DKIT_SERDES_REG_IO_HW_UNLOCK(p_dev->lchip, mcu_id, hss_grp);
    
}

int32 _ctc_at_dkit_serdes_poll_reg_field(ctc_at_dkit_serdes_dev_t* p_dev, _ctc_at_dkit_serdes_field_t* p_field, 
                                                uint8 reg_type, uint32 exp_value)
{
    uint32 i;
    uint32 data;

    if((!p_dev) || (!p_field))
    {
        return CLI_EOL;
    }
    
    for(i = 0; i < 30000; i++)
    {
        (void)(_ctc_at_dkit_serdes_read_reg_field(p_dev, p_field, reg_type, &data));
        if(data == exp_value)
        {
            return CLI_SUCCESS;
        }
    }
/*
    CTC_DKIT_PRINT("Polling %s 0x%08x (mask 0x%08x) == %u fail!\n", 
        ((p_dev->type == CTC_AT_DKIT_SERDES_56G) ? "56G" : "112G"), 
        p_field->reg, p_field->mask, exp_value);
*/
    return CLI_EOL;
}


int32
ctc_at_dkit_misc_read_serdes(void* para)
{
    uint32 value = 0;
    ctc_dkit_serdes_wr_t* p_para = (ctc_dkit_serdes_wr_t*)para;
    ctc_at_dkit_serdes_dev_t dev = {0};

    DKITS_PTR_VALID_CHECK(p_para);
    DKITS_SERDES_ID_CHECK(p_para->lchip, p_para->serdes_id);
    CTC_DKIT_LCHIP_CHECK(p_para->lchip);
    
    (void)_ctc_at_dkit_serdes_serdes_to_psd(p_para->lchip, p_para->serdes_id, &(p_para->serdes_id));
    _ctc_at_dkit_serdes_dev(p_para->lchip, p_para->serdes_id, &dev);
    if(CTC_DKIT_SERDES_COMMON == p_para->type)
    {
        _ctc_at_dkit_serdes_read_reg(&dev, p_para->addr_offset, &value);
    }
    else
    {
        _ctc_at_dkit_serdes_read_reg_lane(&dev, p_para->addr_offset, 
            CTC_AT_DKIT_SERDES_REG_LANE, &value);
    }
    p_para->data = value;
    
    return CLI_SUCCESS;
}

int32
ctc_at_dkit_misc_write_serdes(void* para)
{
    ctc_dkit_serdes_wr_t* p_para = (ctc_dkit_serdes_wr_t*)para;
    ctc_at_dkit_serdes_dev_t dev = {0};

    DKITS_PTR_VALID_CHECK(p_para);
    DKITS_SERDES_ID_CHECK(p_para->lchip, p_para->serdes_id);
    CTC_DKIT_LCHIP_CHECK(p_para->lchip);
    
    (void)_ctc_at_dkit_serdes_serdes_to_psd(p_para->lchip, p_para->serdes_id, &(p_para->serdes_id));
    _ctc_at_dkit_serdes_dev(p_para->lchip, p_para->serdes_id, &dev);
    if(CTC_DKIT_SERDES_COMMON == p_para->type)
    {
        _ctc_at_dkit_serdes_write_reg(&dev, p_para->addr_offset, p_para->data);
    }
    else
    {
        _ctc_at_dkit_serdes_write_reg_lane(&dev, p_para->addr_offset, 
            CTC_AT_DKIT_SERDES_REG_LANE, p_para->data);
    }

    return CLI_SUCCESS;
}

#define __CTC_AT_DKIT_PIN_REG__ 


void
_ctc_at_dkit_serdes_get_112g_pin_tbl(uint16 pin, uint32* p_tbl_id, uint32* p_fld_id)
{
    uint32 tbl_id = 0;
    uint32 fld_id = 0;
    switch(pin)
    {
        case DKIT_AT112G_PIN_RESET      :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGlobalRst_f;
            break;
        case DKIT_AT112G_PIN_SIF_SEL    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssSifSel_f;
            break;
        case DKIT_AT112G_PIN_DIRECTACCESS:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssDirectAccessEn_f;
            break;
        case DKIT_AT112G_PIN_PHY_MODE   :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPhyMode_f;
            break;
        case DKIT_AT112G_PIN_REFCLK_TX0 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane0_f;
            break;
        case DKIT_AT112G_PIN_REFCLK_TX1 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane1_f;
            break;
        case DKIT_AT112G_PIN_REFCLK_TX2 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane2_f;
            break;
        case DKIT_AT112G_PIN_REFCLK_TX3 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane3_f;
            break;
        case DKIT_AT112G_PIN_REFCLK_RX0 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane0_f;
            break;
        case DKIT_AT112G_PIN_REFCLK_RX1 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane1_f;
            break;
        case DKIT_AT112G_PIN_REFCLK_RX2 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane2_f;
            break;
        case DKIT_AT112G_PIN_REFCLK_RX3 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane3_f;
            break;
        case DKIT_AT112G_PIN_REF_FREF_TX0:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane0_f;
            break;
        case DKIT_AT112G_PIN_REF_FREF_TX1:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane1_f;
            break;
        case DKIT_AT112G_PIN_REF_FREF_TX2:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane2_f;
            break;
        case DKIT_AT112G_PIN_REF_FREF_TX3:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane3_f;
            break;
        case DKIT_AT112G_PIN_REF_FREF_RX0:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane0_f;
            break;
        case DKIT_AT112G_PIN_REF_FREF_RX1:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane1_f;
            break;
        case DKIT_AT112G_PIN_REF_FREF_RX2:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane2_f;
            break;
        case DKIT_AT112G_PIN_REF_FREF_RX3:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane3_f;
            break;
        case DKIT_AT112G_PIN_PHY_GEN_TX0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane0_f;
            break;
        case DKIT_AT112G_PIN_PHY_GEN_TX1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane1_f;
            break;
        case DKIT_AT112G_PIN_PHY_GEN_TX2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane2_f;
            break;
        case DKIT_AT112G_PIN_PHY_GEN_TX3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane3_f;
            break;
        case DKIT_AT112G_PIN_PHY_GEN_RX0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane0_f;
            break;
        case DKIT_AT112G_PIN_PHY_GEN_RX1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane1_f;
            break;
        case DKIT_AT112G_PIN_PHY_GEN_RX2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane2_f;
            break;
        case DKIT_AT112G_PIN_PHY_GEN_RX3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane3_f;
            break;
        case DKIT_AT112G_PIN_PU_PLL0    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane0_f;
            break;
        case DKIT_AT112G_PIN_PU_PLL1    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane1_f;
            break;
        case DKIT_AT112G_PIN_PU_PLL2    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane2_f;
            break;
        case DKIT_AT112G_PIN_PU_PLL3    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane3_f;
            break;
        case DKIT_AT112G_PIN_PU_RX0     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane0_f;
            break;
        case DKIT_AT112G_PIN_PU_RX1     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane1_f;
            break;
        case DKIT_AT112G_PIN_PU_RX2     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane2_f;
            break;
        case DKIT_AT112G_PIN_PU_RX3     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane3_f;
            break;
        case DKIT_AT112G_PIN_PU_TX0     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane0_f;
            break;
        case DKIT_AT112G_PIN_PU_TX1     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane1_f;
            break;
        case DKIT_AT112G_PIN_PU_TX2     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane2_f;
            break;
        case DKIT_AT112G_PIN_PU_TX3     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane3_f;
            break;
        case DKIT_AT112G_PIN_TX_IDLE0   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane0_f;
            break;
        case DKIT_AT112G_PIN_TX_IDLE1   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane1_f;
            break;
        case DKIT_AT112G_PIN_TX_IDLE2   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane2_f;
            break;
        case DKIT_AT112G_PIN_TX_IDLE3   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane3_f;
            break;
        case DKIT_AT112G_PIN_PU_IVREF   :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupIVref_f;
            break;
        case DKIT_AT112G_PIN_RX_TRAIN_EN0:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane0_f;
            break;
        case DKIT_AT112G_PIN_RX_TRAIN_EN1:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane1_f;
            break;
        case DKIT_AT112G_PIN_RX_TRAIN_EN2:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane2_f;
            break;
        case DKIT_AT112G_PIN_RX_TRAIN_EN3:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane3_f;
            break;
        case DKIT_AT112G_PIN_RX_TRAIN_CO0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane0_f;
            break;
        case DKIT_AT112G_PIN_RX_TRAIN_CO1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane1_f;
            break;
        case DKIT_AT112G_PIN_RX_TRAIN_CO2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane2_f;
            break;
        case DKIT_AT112G_PIN_RX_TRAIN_CO3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane3_f;
            break;
        case DKIT_AT112G_PIN_RX_TRAIN_FA0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane0_f;
            break;
        case DKIT_AT112G_PIN_RX_TRAIN_FA1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane1_f;
            break;
        case DKIT_AT112G_PIN_RX_TRAIN_FA2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane2_f;
            break;
        case DKIT_AT112G_PIN_RX_TRAIN_FA3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane3_f;
            break;
        case DKIT_AT112G_PIN_TX_TRAIN_EN0:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane0_f;
            break;
        case DKIT_AT112G_PIN_TX_TRAIN_EN1:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane1_f;
            break;
        case DKIT_AT112G_PIN_TX_TRAIN_EN2:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane2_f;
            break;
        case DKIT_AT112G_PIN_TX_TRAIN_EN3:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane3_f;
            break;
        case DKIT_AT112G_PIN_TX_TRAIN_CO0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane0_f;
            break;
        case DKIT_AT112G_PIN_TX_TRAIN_CO1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane1_f;
            break;
        case DKIT_AT112G_PIN_TX_TRAIN_CO2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane2_f;
            break;
        case DKIT_AT112G_PIN_TX_TRAIN_CO3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane3_f;
            break;
        case DKIT_AT112G_PIN_TX_TRAIN_FA0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane0_f;
            break;
        case DKIT_AT112G_PIN_TX_TRAIN_FA1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane1_f;
            break;
        case DKIT_AT112G_PIN_TX_TRAIN_FA2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane2_f;
            break;
        case DKIT_AT112G_PIN_TX_TRAIN_FA3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane3_f;
            break;
        case DKIT_AT112G_PIN_SQ_DET_LPF0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane0_f;
            break;
        case DKIT_AT112G_PIN_SQ_DET_LPF1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane1_f;
            break;
        case DKIT_AT112G_PIN_SQ_DET_LPF2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane2_f;
            break;
        case DKIT_AT112G_PIN_SQ_DET_LPF3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane3_f;
            break;
        case DKIT_AT112G_PIN_RX_INIT0   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane0_f;
            break;
        case DKIT_AT112G_PIN_RX_INIT1   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane1_f;
            break;
        case DKIT_AT112G_PIN_RX_INIT2   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane2_f;
            break;
        case DKIT_AT112G_PIN_RX_INIT3   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane3_f;
            break;
        case DKIT_AT112G_PIN_RX_INITDONE0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane0_f;
            break;
        case DKIT_AT112G_PIN_RX_INITDONE1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane1_f;
            break;
        case DKIT_AT112G_PIN_RX_INITDONE2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane2_f;
            break;
        case DKIT_AT112G_PIN_RX_INITDONE3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane3_f;
            break;
        case DKIT_AT112G_PIN_AVDD_SEL   :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssAvddSel_f;
            break;
        case DKIT_AT112G_PIN_SPD_CFG    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssSpeedCfg_f;
            break;
        case DKIT_AT112G_PIN_PRAM_RESET  :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramReset_f;
            break;
        case DKIT_AT112G_PIN_PRAM_SOC_EN :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramSocEn_f;
            break;
        case DKIT_AT112G_PIN_PRAM_SIF_SEL:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPramSifSel_f;
            break;
        case DKIT_AT112G_PIN_TX_RST0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane0_f;
            break;
        case DKIT_AT112G_PIN_TX_RST1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane1_f;
            break;
        case DKIT_AT112G_PIN_TX_RST2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane2_f;
            break;
        case DKIT_AT112G_PIN_TX_RST3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane3_f;
            break;
        case DKIT_AT112G_PIN_RX_RST0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane0_f;
            break;
        case DKIT_AT112G_PIN_RX_RST1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane1_f;
            break;
        case DKIT_AT112G_PIN_RX_RST2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane2_f;
            break;
        case DKIT_AT112G_PIN_RX_RST3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane3_f;
            break;
        case DKIT_AT112G_PIN_FW_READY:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssFwReady_f;
            break;
        case DKIT_AT112G_PIN_PLL_RDY_RX0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane0_f;
            break;
        case DKIT_AT112G_PIN_PLL_RDY_RX1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane1_f;
            break;
        case DKIT_AT112G_PIN_PLL_RDY_RX2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane2_f;
            break;
        case DKIT_AT112G_PIN_PLL_RDY_RX3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane3_f;
            break;
        case DKIT_AT112G_PIN_PLL_RDY_TX0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane0_f;
            break;
        case DKIT_AT112G_PIN_PLL_RDY_TX1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane1_f;
            break;
        case DKIT_AT112G_PIN_PLL_RDY_TX2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane2_f;
            break;
        case DKIT_AT112G_PIN_PLL_RDY_TX3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane3_f;
            break;
        case DKIT_AT112G_PIN_TX_RST_ACK0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane0_f;
            break;
        case DKIT_AT112G_PIN_TX_RST_ACK1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane1_f;
            break;
        case DKIT_AT112G_PIN_TX_RST_ACK2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane2_f;
            break;
        case DKIT_AT112G_PIN_TX_RST_ACK3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane3_f;
            break;
        case DKIT_AT112G_PIN_RX_RST_ACK0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane0_f;
            break;
        case DKIT_AT112G_PIN_RX_RST_ACK1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane1_f;
            break;
        case DKIT_AT112G_PIN_RX_RST_ACK2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane2_f;
            break;
        case DKIT_AT112G_PIN_RX_RST_ACK3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane3_f;
            break;
        case DKIT_AT112G_PIN_RX_GRAYCODE_EN0 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane0_f;
            break;
        case DKIT_AT112G_PIN_RX_GRAYCODE_EN1 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane1_f;
            break;
        case DKIT_AT112G_PIN_RX_GRAYCODE_EN2 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane2_f;
            break;
        case DKIT_AT112G_PIN_RX_GRAYCODE_EN3 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane3_f;
            break;
        case DKIT_AT112G_PIN_TX_GRAYCODE_EN0 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane0_f;
            break;
        case DKIT_AT112G_PIN_TX_GRAYCODE_EN1 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane1_f;
            break;
        case DKIT_AT112G_PIN_TX_GRAYCODE_EN2 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane2_f;
            break;
        case DKIT_AT112G_PIN_TX_GRAYCODE_EN3 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane3_f;
            break;
        case DKIT_AT112G_PIN_RX_PRECODE_EN0:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane0_f;
            break;
        case DKIT_AT112G_PIN_RX_PRECODE_EN1:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane1_f;
            break;
        case DKIT_AT112G_PIN_RX_PRECODE_EN2:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane2_f;
            break;
        case DKIT_AT112G_PIN_RX_PRECODE_EN3:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane3_f;
            break;
        case DKIT_AT112G_PIN_TX_PRECODE_EN0:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane0_f;
            break;
        case DKIT_AT112G_PIN_TX_PRECODE_EN1:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane1_f;
            break;
        case DKIT_AT112G_PIN_TX_PRECODE_EN2:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane2_f;
            break;
        case DKIT_AT112G_PIN_TX_PRECODE_EN3:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane3_f;
            break;
        case DKIT_AT112G_PIN_MCU_CLK:
            tbl_id = HssMcuCfg_t;
            fld_id = HssMcuCfg_cfgHssMcuFreq_f;
            break;
        case DKIT_AT112G_PIN_FORCE_PMA_RDY_EN0  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane0_f;
            break;
        case DKIT_AT112G_PIN_FORCE_PMA_RDY_EN1  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane1_f;
            break;
        case DKIT_AT112G_PIN_FORCE_PMA_RDY_EN2  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane2_f;
            break;
        case DKIT_AT112G_PIN_FORCE_PMA_RDY_EN3  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane3_f;
            break;
        case DKIT_AT112G_PIN_FORCE_PMA_RDY_VAL0 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane0_f;
            break;
        case DKIT_AT112G_PIN_FORCE_PMA_RDY_VAL1 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane1_f;
            break;
        case DKIT_AT112G_PIN_FORCE_PMA_RDY_VAL2 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane2_f;
            break;
        case DKIT_AT112G_PIN_FORCE_PMA_RDY_VAL3 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane3_f;
            break;
        case DKIT_AT112G_PIN_PRAM_CHECKSUM_RESET :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramChecksumReset_f;
            break;
        case DKIT_AT112G_PIN_PRAM_CHECKSUM :
            tbl_id = HssPramMon_t;
            fld_id = HssPramMon_monPramChecksum_f;
            break;
        case DKIT_AT112G_PIN_PRAM_CHECKSUM_EN :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramChecksumEn_f;
            break;
        case DKIT_AT112G_PIN_PRAM_CHECKSUM_SEL :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramChecksumSel_f;
            break;
        case DKIT_AT112G_PIN_MCU_INIT_DONE :
            tbl_id = HssMcuMon_t;
            fld_id = HssMcuMon_monHssMcuInitDone_f;
            break;
        case DKIT_AT112G_PIN_RX_DTL_CLAMP0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane0_f;
            break;
        case DKIT_AT112G_PIN_RX_DTL_CLAMP1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane1_f;
            break;
        case DKIT_AT112G_PIN_RX_DTL_CLAMP2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane2_f;
            break;
        case DKIT_AT112G_PIN_RX_DTL_CLAMP3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane3_f;
            break;
        default:
            tbl_id = 0;
            fld_id = 0;
            break;
    }
    *p_tbl_id = tbl_id;
    *p_fld_id = fld_id;
}

void
_ctc_at_dkit_serdes_get_56g_pin_tbl(uint16 pin, uint32* p_tbl_id, uint32* p_fld_id)
{
    uint32 tbl_id = 0;
    uint32 fld_id = 0;
    switch(pin)
    {
        case DKIT_AT56G_PIN_RESET      :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGlobalRst_f;
            break;
        case DKIT_AT56G_PIN_SIF_SEL    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssSifSel_f;
            break;
        case DKIT_AT56G_PIN_DIRECTACCES:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssDirectAccessEn_f;
            break;
        case DKIT_AT56G_PIN_PHY_MODE   :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPhyMode_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_TX0 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane0_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_TX1 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane1_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_TX2 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane2_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_TX3 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelTxLane3_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_RX0 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane0_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_RX1 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane1_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_RX2 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane2_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_RX3 :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRefClkSelRxLane3_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_TX0:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane0_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_TX1:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane1_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_TX2:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane2_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_TX3:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssRefFrefSelTxLane3_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_RX0:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane0_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_RX1:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane1_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_RX2:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane2_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_RX3:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRefFrefSelRxLane3_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_TX0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane0_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_TX1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane1_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_TX2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane2_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_TX3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenTxLane3_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_RX0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane0_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_RX1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane1_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_RX2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane2_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_RX3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssGenRxLane3_f;
            break;
        case DKIT_AT56G_PIN_PU_PLL0    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane0_f;
            break;
        case DKIT_AT56G_PIN_PU_PLL1    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane1_f;
            break;
        case DKIT_AT56G_PIN_PU_PLL2    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane2_f;
            break;
        case DKIT_AT56G_PIN_PU_PLL3    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupPllLane3_f;
            break;
        case DKIT_AT56G_PIN_PU_RX0     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane0_f;
            break;
        case DKIT_AT56G_PIN_PU_RX1     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane1_f;
            break;
        case DKIT_AT56G_PIN_PU_RX2     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane2_f;
            break;
        case DKIT_AT56G_PIN_PU_RX3     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupRxLane3_f;
            break;
        case DKIT_AT56G_PIN_PU_TX0     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane0_f;
            break;
        case DKIT_AT56G_PIN_PU_TX1     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane1_f;
            break;
        case DKIT_AT56G_PIN_PU_TX2     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane2_f;
            break;
        case DKIT_AT56G_PIN_PU_TX3     :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupTxLane3_f;
            break;
        case DKIT_AT56G_PIN_TX_IDLE0   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_IDLE1   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_IDLE2   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_IDLE3   :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxIdleLane3_f;
            break;
        case DKIT_AT56G_PIN_PU_IVREF   :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssPowerupIVref_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINEN0:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINEN1:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINEN2:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINEN3:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxTrainEnableLane3_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINCO0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINCO1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINCO2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINCO3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainCompleteLane3_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINFA0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINFA1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINFA2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINFA3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxTrainFailedLane3_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINEN0:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINEN1:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINEN2:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINEN3:
            tbl_id = HssTxTrainCfg_t;
            fld_id = HssTxTrainCfg_cfgHssTxTrainEnableLane3_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINCO0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINCO1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINCO2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINCO3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainCompleteLane3_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINFA0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINFA1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINFA2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINFA3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxTrainFailedLane3_f;
            break;
        case DKIT_AT56G_PIN_SQ_DET_LPF0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane0_f;
            break;
        case DKIT_AT56G_PIN_SQ_DET_LPF1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane1_f;
            break;
        case DKIT_AT56G_PIN_SQ_DET_LPF2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane2_f;
            break;
        case DKIT_AT56G_PIN_SQ_DET_LPF3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxSquelchDetLpfLane3_f;
            break;
        case DKIT_AT56G_PIN_RX_INIT0   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_INIT1   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_INIT2   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_INIT3   :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxInitLane3_f;
            break;
        case DKIT_AT56G_PIN_RX_INITDON0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_INITDON1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_INITDON2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_INITDON3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxInitDoneLane3_f;
            break;
        case DKIT_AT56G_PIN_AVDD_SEL   :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssAvddSel_f;
            break;
        case DKIT_AT56G_PIN_SPD_CFG    :
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssSpeedCfg_f;
            break;
        case DKIT_AT56G_PIN_TX_RST0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_RST1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_RST2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_RST3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssTxRstLane3_f;
            break;
        case DKIT_AT56G_PIN_RX_RST0:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_RST1:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_RST2:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_RST3:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssRxRstLane3_f;
            break;
        case DKIT_AT56G_PIN_PRAM_RESET:
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramReset_f;
            break;
        case DKIT_AT56G_PIN_FW_READY:
            tbl_id = HssCmnCfg_t;
            fld_id = HssCmnCfg_cfgHssFwReady_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_RX0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane0_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_RX1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane1_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_RX2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane2_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_RX3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyRxLane3_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_TX0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane0_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_TX1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane1_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_TX2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane2_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_TX3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssPllReadyTxLane3_f;
            break;
        case DKIT_AT56G_PIN_TX_RST_ACK0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_RST_ACK1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_RST_ACK2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_RST_ACK3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssTxRstAckLane3_f;
            break;
        case DKIT_AT56G_PIN_RX_RST_ACK0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_RST_ACK1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_RST_ACK2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_RST_ACK3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxRstAckLane3_f;
            break;
        case DKIT_AT56G_PIN_PRAM_SOC_EN :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramSocEn_f;
            break;
        case DKIT_AT56G_PIN_RX_GRAYCODE_EN0 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_GRAYCODE_EN1 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_GRAYCODE_EN2 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_GRAYCODE_EN3 :
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxGrayCodeEnLane3_f;
            break;
        case DKIT_AT56G_PIN_TX_GRAYCODE_EN0 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_GRAYCODE_EN1 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_GRAYCODE_EN2 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_GRAYCODE_EN3 :
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxGrayCodeEnLane3_f;
            break;
        case DKIT_AT56G_PIN_RX_PRECODE_EN0:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_PRECODE_EN1:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_PRECODE_EN2:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_PRECODE_EN3:
            tbl_id = HssRxCfg_t;
            fld_id = HssRxCfg_cfgHssRxPreCodeEnLane3_f;
            break;
        case DKIT_AT56G_PIN_TX_PRECODE_EN0:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_PRECODE_EN1:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_PRECODE_EN2:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_PRECODE_EN3:
            tbl_id = HssTxCfg_t;
            fld_id = HssTxCfg_cfgHssTxPreCodeEnLane3_f;
            break;
        case DKIT_AT56G_PIN_MCU_CLK:
            tbl_id = HssMcuCfg_t;
            fld_id = HssMcuCfg_cfgHssMcuFreq_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_EN0  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane0_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_EN1  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane1_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_EN2  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane2_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_EN3  :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsEnLane3_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_VAL0 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane0_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_VAL1 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane1_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_VAL2 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane2_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_VAL3 :
            tbl_id = HssLaneCfg_t;
            fld_id = HssLaneCfg_cfgForcePmaReady4PcsValueLane3_f;
            break;
        case DKIT_AT56G_PIN_PRAM_CHECKSUM_RESET :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramChecksumReset_f;
            break;
        case DKIT_AT56G_PIN_PRAM_CHECKSUM :
            tbl_id = HssPramMon_t;
            fld_id = HssPramMon_monPramChecksum_f;
            break;
        case DKIT_AT56G_PIN_RX_DTL_CLAMP0:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_DTL_CLAMP1:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_DTL_CLAMP2:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_DTL_CLAMP3:
            tbl_id = HssMon_t;
            fld_id = HssMon_monHssRxDtlClampLane3_f;
            break;
        case DKIT_AT56G_PIN_PRAM_CHECKSUM_EN :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramChecksumEn_f;
            break;
        case DKIT_AT56G_PIN_PRAM_CHECKSUM_SEL :
            tbl_id = HssPramCfg_t;
            fld_id = HssPramCfg_cfgPramChecksumSel_f;
            break;
        case DKIT_AT56G_PIN_MCU_INIT_DONE :
            tbl_id = HssMcuMon_t;
            fld_id = HssMcuMon_monHssMcuInitDone_f;
            break;
        default:
            tbl_id = 0;
            fld_id = 0;
            break;
    }
    *p_tbl_id = tbl_id;
    *p_fld_id = fld_id;
}


void
_ctc_at_dkit_serdes_get_cpumac_56g_pin_tbl(uint16 pin, uint32* p_tbl_id, uint32* p_fld_id)
{
    uint32 tbl_id = 0;
    uint32 fld_id = 0;
    switch(pin)
    {
        case DKIT_AT56G_PIN_RESET      :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGlobalRst_f;
            break;
        case DKIT_AT56G_PIN_SIF_SEL    :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssSifSel_f;
            break;
        case DKIT_AT56G_PIN_DIRECTACCES:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssDirectAccessEn_f;
            break;
        case DKIT_AT56G_PIN_PHY_MODE   :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPhyMode_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_TX0 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelTxLane0_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_TX1 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelTxLane1_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_TX2 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelTxLane2_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_TX3 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelTxLane3_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_RX0 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelRxLane0_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_RX1 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelRxLane1_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_RX2 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelRxLane2_f;
            break;
        case DKIT_AT56G_PIN_REFCLK_RX3 :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRefClkSelRxLane3_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_TX0:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssRefFrefSelTxLane0_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_TX1:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssRefFrefSelTxLane1_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_TX2:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssRefFrefSelTxLane2_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_TX3:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssRefFrefSelTxLane3_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_RX0:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRefFrefSelRxLane0_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_RX1:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRefFrefSelRxLane1_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_RX2:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRefFrefSelRxLane2_f;
            break;
        case DKIT_AT56G_PIN_REFFREF_RX3:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRefFrefSelRxLane3_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_TX0:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenTxLane0_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_TX1:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenTxLane1_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_TX2:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenTxLane2_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_TX3:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenTxLane3_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_RX0:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenRxLane0_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_RX1:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenRxLane1_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_RX2:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenRxLane2_f;
            break;
        case DKIT_AT56G_PIN_PHY_GEN_RX3:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssGenRxLane3_f;
            break;
        case DKIT_AT56G_PIN_PU_PLL0    :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupPllLane0_f;
            break;
        case DKIT_AT56G_PIN_PU_PLL1    :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupPllLane1_f;
            break;
        case DKIT_AT56G_PIN_PU_PLL2    :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupPllLane2_f;
            break;
        case DKIT_AT56G_PIN_PU_PLL3    :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupPllLane3_f;
            break;
        case DKIT_AT56G_PIN_PU_RX0     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupRxLane0_f;
            break;
        case DKIT_AT56G_PIN_PU_RX1     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupRxLane1_f;
            break;
        case DKIT_AT56G_PIN_PU_RX2     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupRxLane2_f;
            break;
        case DKIT_AT56G_PIN_PU_RX3     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupRxLane3_f;
            break;
        case DKIT_AT56G_PIN_PU_TX0     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupTxLane0_f;
            break;
        case DKIT_AT56G_PIN_PU_TX1     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupTxLane1_f;
            break;
        case DKIT_AT56G_PIN_PU_TX2     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupTxLane2_f;
            break;
        case DKIT_AT56G_PIN_PU_TX3     :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupTxLane3_f;
            break;
        case DKIT_AT56G_PIN_TX_IDLE0   :
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxIdleLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_IDLE1   :
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxIdleLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_IDLE2   :
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxIdleLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_IDLE3   :
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxIdleLane3_f;
            break;
        case DKIT_AT56G_PIN_PU_IVREF   :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssPowerupIVref_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINEN0:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxTrainEnableLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINEN1:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxTrainEnableLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINEN2:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxTrainEnableLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINEN3:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxTrainEnableLane3_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINCO0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainCompleteLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINCO1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainCompleteLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINCO2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainCompleteLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINCO3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainCompleteLane3_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINFA0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainFailedLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINFA1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainFailedLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINFA2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainFailedLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_TRAINFA3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxTrainFailedLane3_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINEN0:
            tbl_id = CpuMacHssTxTrainCfg_t;
            fld_id = CpuMacHssTxTrainCfg_cfgHssTxTrainEnableLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINEN1:
            tbl_id = CpuMacHssTxTrainCfg_t;
            fld_id = CpuMacHssTxTrainCfg_cfgHssTxTrainEnableLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINEN2:
            tbl_id = CpuMacHssTxTrainCfg_t;
            fld_id = CpuMacHssTxTrainCfg_cfgHssTxTrainEnableLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINEN3:
            tbl_id = CpuMacHssTxTrainCfg_t;
            fld_id = CpuMacHssTxTrainCfg_cfgHssTxTrainEnableLane3_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINCO0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainCompleteLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINCO1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainCompleteLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINCO2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainCompleteLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINCO3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainCompleteLane3_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINFA0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainFailedLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINFA1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainFailedLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINFA2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainFailedLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_TRAINFA3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxTrainFailedLane3_f;
            break;
        case DKIT_AT56G_PIN_SQ_DET_LPF0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxSquelchDetLpfLane0_f;
            break;
        case DKIT_AT56G_PIN_SQ_DET_LPF1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxSquelchDetLpfLane1_f;
            break;
        case DKIT_AT56G_PIN_SQ_DET_LPF2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxSquelchDetLpfLane2_f;
            break;
        case DKIT_AT56G_PIN_SQ_DET_LPF3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxSquelchDetLpfLane3_f;
            break;
        case DKIT_AT56G_PIN_RX_INIT0   :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxInitLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_INIT1   :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxInitLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_INIT2   :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxInitLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_INIT3   :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxInitLane3_f;
            break;
        case DKIT_AT56G_PIN_RX_INITDON0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxInitDoneLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_INITDON1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxInitDoneLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_INITDON2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxInitDoneLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_INITDON3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxInitDoneLane3_f;
            break;
        case DKIT_AT56G_PIN_AVDD_SEL   :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssAvddSel_f;
            break;
        case DKIT_AT56G_PIN_SPD_CFG    :
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssSpeedCfg_f;
            break;
        case DKIT_AT56G_PIN_TX_RST0:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssTxRstLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_RST1:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssTxRstLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_RST2:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssTxRstLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_RST3:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssTxRstLane3_f;
            break;
        case DKIT_AT56G_PIN_RX_RST0:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRxRstLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_RST1:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRxRstLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_RST2:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRxRstLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_RST3:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssRxRstLane3_f;
            break;
        case DKIT_AT56G_PIN_PRAM_RESET:
            tbl_id = CpuMacHssPramCfg_t;
            fld_id = CpuMacHssPramCfg_cfgPramReset_f;
            break;
        case DKIT_AT56G_PIN_FW_READY:
            tbl_id = CpuMacHssCmnCfg_t;
            fld_id = CpuMacHssCmnCfg_cfgHssFwReady_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_RX0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyRxLane0_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_RX1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyRxLane1_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_RX2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyRxLane2_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_RX3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyRxLane3_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_TX0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyTxLane0_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_TX1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyTxLane1_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_TX2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyTxLane2_f;
            break;
        case DKIT_AT56G_PIN_PLL_RDY_TX3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssPllReadyTxLane3_f;
            break;
        case DKIT_AT56G_PIN_TX_RST_ACK0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxRstAckLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_RST_ACK1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxRstAckLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_RST_ACK2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxRstAckLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_RST_ACK3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssTxRstAckLane3_f;
            break;
        case DKIT_AT56G_PIN_RX_RST_ACK0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxRstAckLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_RST_ACK1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxRstAckLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_RST_ACK2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxRstAckLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_RST_ACK3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxRstAckLane3_f;
            break;
        case DKIT_AT56G_PIN_PRAM_SOC_EN :
            tbl_id = CpuMacHssPramCfg_t;
            fld_id = CpuMacHssPramCfg_cfgPramSocEn_f;
            break;
        case DKIT_AT56G_PIN_RX_GRAYCODE_EN0 :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxGrayCodeEnLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_GRAYCODE_EN1 :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxGrayCodeEnLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_GRAYCODE_EN2 :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxGrayCodeEnLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_GRAYCODE_EN3 :
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxGrayCodeEnLane3_f;
            break;
        case DKIT_AT56G_PIN_TX_GRAYCODE_EN0:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxGrayCodeEnLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_GRAYCODE_EN1:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxGrayCodeEnLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_GRAYCODE_EN2:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxGrayCodeEnLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_GRAYCODE_EN3:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxGrayCodeEnLane3_f;
            break;
        case DKIT_AT56G_PIN_RX_PRECODE_EN0:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxPreCodeEnLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_PRECODE_EN1:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxPreCodeEnLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_PRECODE_EN2:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxPreCodeEnLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_PRECODE_EN3:
            tbl_id = CpuMacHssRxCfg_t;
            fld_id = CpuMacHssRxCfg_cfgHssRxPreCodeEnLane3_f;
            break;
        case DKIT_AT56G_PIN_TX_PRECODE_EN0:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxPreCodeEnLane0_f;
            break;
        case DKIT_AT56G_PIN_TX_PRECODE_EN1:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxPreCodeEnLane1_f;
            break;
        case DKIT_AT56G_PIN_TX_PRECODE_EN2:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxPreCodeEnLane2_f;
            break;
        case DKIT_AT56G_PIN_TX_PRECODE_EN3:
            tbl_id = CpuMacHssTxCfg_t;
            fld_id = CpuMacHssTxCfg_cfgHssTxPreCodeEnLane3_f;
            break;
        case DKIT_AT56G_PIN_MCU_CLK:
            tbl_id = CpuMacHssMcuCfg_t;
            fld_id = CpuMacHssMcuCfg_cfgHssMcuFreq_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_EN0  :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsEnLane0_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_EN1  :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsEnLane1_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_EN2  :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsEnLane2_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_EN3  :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsEnLane3_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_VAL0 :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsValueLane0_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_VAL1 :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsValueLane1_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_VAL2 :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsValueLane2_f;
            break;
        case DKIT_AT56G_PIN_FORCE_PMA_RDY_VAL3 :
            tbl_id = CpuMacHssLaneCfg_t;
            fld_id = CpuMacHssLaneCfg_cfgForcePmaReady4PcsValueLane3_f;
            break;
        case DKIT_AT56G_PIN_PRAM_CHECKSUM_RESET :
            tbl_id = CpuMacHssPramCfg_t;
            fld_id = CpuMacHssPramCfg_cfgPramChecksumReset_f;
            break;
        case DKIT_AT56G_PIN_PRAM_CHECKSUM :
            tbl_id = CpuMacHssPramMon_t;
            fld_id = CpuMacHssPramMon_monPramChecksum_f;
            break;
        case DKIT_AT56G_PIN_RX_DTL_CLAMP0:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxDtlClampLane0_f;
            break;
        case DKIT_AT56G_PIN_RX_DTL_CLAMP1:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxDtlClampLane1_f;
            break;
        case DKIT_AT56G_PIN_RX_DTL_CLAMP2:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxDtlClampLane2_f;
            break;
        case DKIT_AT56G_PIN_RX_DTL_CLAMP3:
            tbl_id = CpuMacHssMon_t;
            fld_id = CpuMacHssMon_monHssRxDtlClampLane3_f;
            break;
        case DKIT_AT56G_PIN_PRAM_CHECKSUM_EN :
            tbl_id = CpuMacHssPramCfg_t;
            fld_id = CpuMacHssPramCfg_cfgPramChecksumEn_f;
            break;
        case DKIT_AT56G_PIN_PRAM_CHECKSUM_SEL :
            tbl_id = CpuMacHssPramCfg_t;
            fld_id = CpuMacHssPramCfg_cfgPramChecksumSel_f;
            break;
        case DKIT_AT56G_PIN_MCU_INIT_DONE :
            tbl_id = CpuMacHssMcuMon_t;
            fld_id = CpuMacHssMcuMon_monHssMcuInitDone_f;
            break;
        default:
            tbl_id = 0;
            fld_id = 0;
            break;
    }
    *p_tbl_id = tbl_id;
    *p_fld_id = fld_id;
}

void ctc_at_dkit_serdes_get_pin_tbl(ctc_at_dkit_serdes_dev_t* p_dev, uint16 pin, uint32* tbl_id, uint32* fld_id)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        if(CTC_DKIT_AT_IS_CPUMAC_SERDES(p_dev->serdes_id))
        {
            _ctc_at_dkit_serdes_get_cpumac_56g_pin_tbl(pin, tbl_id, fld_id);
        }
        else
        {
            _ctc_at_dkit_serdes_get_56g_pin_tbl(pin, tbl_id, fld_id);
        }
    }
    else
    {
        _ctc_at_dkit_serdes_get_112g_pin_tbl(pin, tbl_id, fld_id);
    }
}


void 
_ctc_at_dkit_serdes_get_pin(ctc_at_dkit_serdes_dev_t* p_dev, uint16 pin, uint16 *value)
{
    uint8  grp_id = CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    uint8  ins    = CTC_DKIT_AT_IS_CPUMAC_SERDES(p_dev->serdes_id) ? 0 : grp_id;
    uint8  core   = CTC_DKIT_AT_GET_CORE_ID_BY_LOGIC_SERDES(p_dev->serdes_id);
    uint32 tbl_id = 0;
    uint32 fld_id = 0;
    uint32 index  = DRV_INS(ins, 0);
    uint32 cmd    = 0;
    uint32 val[16] = {0};
    uint32 val32  = 0;

    ctc_at_dkit_serdes_get_pin_tbl(p_dev, pin, &tbl_id, &fld_id);

    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    (void)(DKIT_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));
    DRV_IOR_FIELD(p_dev->lchip, tbl_id, fld_id, &val32, val);
    *value = (uint16)val32;
}

void 
_ctc_at_dkit_serdes_set_pin(ctc_at_dkit_serdes_dev_t* p_dev, uint16 pin, uint16 value)
{
    uint8  grp_id = CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    uint8  ins    = CTC_DKIT_AT_IS_CPUMAC_SERDES(p_dev->serdes_id) ? 0 : grp_id;
    uint8  core   = CTC_DKIT_AT_GET_CORE_ID_BY_LOGIC_SERDES(p_dev->serdes_id);
    uint32 tbl_id = 0;
    uint32 fld_id = 0;
    uint32 index  = DRV_INS(ins, 0);
    uint32 cmd    = 0;
    uint32 val[16] = {0};
    uint32 val32  = value;

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        if(CTC_DKIT_AT_IS_CPUMAC_SERDES(p_dev->serdes_id))
        {
            _ctc_at_dkit_serdes_get_cpumac_56g_pin_tbl(pin, &tbl_id, &fld_id);
        }
        else
        {
            _ctc_at_dkit_serdes_get_56g_pin_tbl(pin, &tbl_id, &fld_id);
        }
    }
    else
    {
        _ctc_at_dkit_serdes_get_112g_pin_tbl(pin, &tbl_id, &fld_id);
    }

    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    (void)(DKIT_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));
    DKIT_DRV_IOW_FIELD_NZ(core, 0xff, 0xff, p_dev->lchip, tbl_id, ins, fld_id, &val32, val);
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    (void)(DKIT_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));
}

/*Warning: all pin must in one tbl!*/
void
_ctc_at_dkit_serdes_set_pin_array(ctc_at_dkit_serdes_dev_t* p_dev, uint8 pin_num, uint16 pin[], uint32 value[])
{
    uint8  grp_id     = CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    uint8  ins        = CTC_DKIT_AT_IS_CPUMAC_SERDES(p_dev->serdes_id) ? 0 : grp_id;
    uint8  core       = CTC_DKIT_AT_GET_CORE_ID_BY_LOGIC_SERDES(p_dev->serdes_id);
    uint32 tbl_id     = 0;
    uint32 tmp_tbl_id = 0;
    uint32 fld_id     = 0;
    uint32 index      = DRV_INS(ins, 0);
    uint32 cmd        = 0;
    uint32 val[16]    = {0};
    uint32 val32      = 0;
    uint8  i          = 0;

    ctc_at_dkit_serdes_get_pin_tbl(p_dev, pin[0], &tbl_id, &fld_id);
    for(i = 1; i < pin_num; i++)
    {
        ctc_at_dkit_serdes_get_pin_tbl(p_dev, pin[i], &tmp_tbl_id, &fld_id);
        if(tbl_id != tmp_tbl_id)
        {
            CTC_DKIT_PRINT("Error: all pin must in one tbl!\n");
            return; 
        }
    }

    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    (void)(DKIT_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));

    for(i = 0; i < pin_num; i++)
    {
        ctc_at_dkit_serdes_get_pin_tbl(p_dev, pin[i], &tbl_id, &fld_id);
        val32 = value[i];
        DKIT_DRV_IOW_FIELD_NZ(core, 0xff, 0xff, p_dev->lchip, tbl_id, ins, fld_id, &val32, val);
    }

    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    (void)(DKIT_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));
}

void _ctc_at_dkit_serdes_poll_pin(ctc_at_dkit_serdes_dev_t* p_dev, uint16 pin, uint16 exp_value)
{
    uint32 i;
    uint16 data;

    for(i = 0; i < 500000; i++)
    {
        _ctc_at_dkit_serdes_get_pin(p_dev, pin, &data);
        if(data == exp_value)
        {
            return;
        }
    }
    CTC_DKIT_PRINT("Polling %s pin %u == %u fail!\n", 
        ((p_dev->type == CTC_AT_DKIT_SERDES_56G) ? "56G" : "112G"), pin, exp_value);
    return;
}

uint8
_ctc_at_dkit_get_chip_type(uint8 lchip)
{
    uint32 product_number = 0;
    (void)drv_usw_chip_read(lchip, 0x00890320, &product_number);  /* tbl ChipPartNumber */
#if (SDK_WORK_PLATFORM == 1)
    product_number = 9;
#endif
    switch (product_number)
    {
    case 2:
        return CTC_DKIT_AT_SUBTYPE_1;  /* CTC9260 */
    case 4:
        return CTC_DKIT_AT_SUBTYPE_2;  /* CTC9262 */
    case 9:
        return CTC_DKIT_AT_SUBTYPE_3;  /* CTC9280 */
    case 12:
    default:
        return CTC_DKIT_AT_SUBTYPE_4;  /* CTC9282 */
    }
#if 0
#ifdef EMULATOR_ENV
    //uint8 chip_type = CTC_DKIT_AT_SUBTYPE_M8_PG1;
    uint8 chip_type = CTC_DKIT_AT_SUBTYPE_M6_1;
    //uint8 chip_type = CTC_DKIT_AT_SUBTYPE_M7;
#elif(1 == SDK_WORK_PLATFORM)
    uint8 chip_type = CTC_DKIT_AT_SUBTYPE_M6_1;
#elif defined(DMPS_1PP0)
    uint8 chip_type = CTC_DKIT_AT_SUBTYPE_1PP_0;
#elif defined(DMPS_1PP1)
    uint8 chip_type = CTC_DKIT_AT_SUBTYPE_1PP_1;
#elif defined(DMPS_1PP2)
    uint8 chip_type = CTC_DKIT_AT_SUBTYPE_1PP_2;
#else
    uint8 chip_type = CTC_DKIT_AT_SUBTYPE_M7;
#endif

#if 0
    char* subtype_name[] = {
        "M8",  
        "M7",  
        "M6_0",
        "M6_1",
        "M6_2",
        "M5_0",
        "M5_1",
        "M5_2",
        "M5_3",
    };


    sal_printf("current subtype is %s\n", subtype_name[chip_type]);
#endif
    return chip_type;
#endif
}


uint8
_ctc_at_dkit_chip_is_dc(uint8 lchip)
{
    uint8 chip_type = _ctc_at_dkit_get_chip_type(lchip);

    if ((CTC_DKIT_AT_SUBTYPE_3 == chip_type)
        || (CTC_DKIT_AT_SUBTYPE_4 == chip_type))
    {
        return TRUE;
    }

    return FALSE;
}

uint8 _ctc_at_dkit_get_serdes_type(uint8 lchip, uint16 serdes_id)
{
    uint16 spsd = serdes_id % CTC_DKIT_AT_NW_SERDES_NUM_PER_CORE;

    if(spsd >= CTC_DKIT_AT_112G_SERDES_FIRST && spsd <= CTC_DKIT_AT_112G_SERDES_LAST)
    {
        return CTC_AT_DKIT_SERDES_112G;
    }
    else 
    {
        return CTC_AT_DKIT_SERDES_56G;
    }
}

#define _AT_SERDES_PROPERTY_


void
_ctc_at_dkit_get_pll_lock(ctc_at_dkit_serdes_dev_t* p_dev, uint8 *tx_lock, uint8* rx_lock)
{
    uint32 value = 0;
    
    if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_PLL_TS_LOCK_RD), CTC_AT_DKIT_SERDES_REG_LANE, &value);
        *tx_lock = (uint8)value;
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_PLL_RS_LOCK_RD), CTC_AT_DKIT_SERDES_REG_LANE, &value);
        *rx_lock = (uint8)value;
    }
    else if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_PLL_TS_LOCK), CTC_AT_DKIT_SERDES_REG_LANE, &value);
        *tx_lock = (uint8)value;
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_PLL_RS_LOCK), CTC_AT_DKIT_SERDES_REG_LANE, &value);
        *rx_lock = (uint8)value;
    }
}

void
_ctc_at_dkit_get_txrx_ready(ctc_at_dkit_serdes_dev_t* p_dev, uint8 *tx_ready, uint8* rx_ready)
{
    uint16 value = 0;
    uint16 value1 = 0;
    uint8  lane;

    lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    
    if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_RX0, &value);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_TX0, &value1);
                break;
            case 1:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_RX1, &value);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_TX1, &value1);
                break;
            case 2:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_RX2, &value);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_TX2, &value1);
                break;
            case 3:
            default:    
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_RX3, &value);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_TX3, &value1);
                break;
        }
    }
    else if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_RX0, &value);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_TX0, &value1);
                break;
            case 1:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_RX1, &value);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_TX1, &value1);
                break;
            case 2:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_RX2, &value);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_TX2, &value1);
                break;
            case 3:
            default:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_RX3, &value);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_TX3, &value1);
                break;
        }
    }

    *tx_ready = (uint8)value1;
    *rx_ready = (uint8)value;
}

void _ctc_at_dkit_56g_get_txeq_param(ctc_at_dkit_serdes_dev_t* p_dev, uint8 param, int32* value)
{
    uint32 data, position;
    uint32 paramUnsignedValue = 0;
    int32 paramSign;
    
    *value = 0;
    switch (param)
    {
        case DKIT_AT56G_TXEQ_EM_PRE3:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ANA_TX_C0), CTC_AT_DKIT_SERDES_REG_LANE, &paramUnsignedValue);
            break;
        case DKIT_AT56G_TXEQ_EM_PRE2:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ANA_TX_C1), CTC_AT_DKIT_SERDES_REG_LANE, &paramUnsignedValue);
            break;
        case DKIT_AT56G_TXEQ_EM_PRE:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ANA_TX_C2), CTC_AT_DKIT_SERDES_REG_LANE, &paramUnsignedValue);
            break;
        case DKIT_AT56G_TXEQ_EM_MAIN:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ANA_TX_C3), CTC_AT_DKIT_SERDES_REG_LANE, &paramUnsignedValue);
            break;
        case DKIT_AT56G_TXEQ_EM_POST:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ANA_TX_C4), CTC_AT_DKIT_SERDES_REG_LANE, &paramUnsignedValue);
            break;
        case DKIT_AT56G_TXEQ_EM_NA:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ANA_TX_C5), CTC_AT_DKIT_SERDES_REG_LANE, &paramUnsignedValue);
            break;
        default:
            break;
     }

    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TO_ANA_TX_FIR_POL), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    position = param;               /* N5XC56GP5X4_TXEQ_EM_PRE2 1, N5XC56GP5X4_TXEQ_EM_PRE 2, ... */
    paramSign = ((data >> position) & 0x1) == 0 ? /* normal */ -1 : /* inverted */ 1;
    *value = paramSign * paramUnsignedValue;
}

void _ctc_at_dkit_112g_get_txeq_param(ctc_at_dkit_serdes_dev_t* p_dev, uint8 param, int32* p_value)
{
    uint32 data;
    uint32 param_unsigned_value = 0;
    int32  param_sign;

    *p_value = 0;

    switch (param)
    {
        case DKIT_AT112G_TXEQ_EM_PRE3:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ANA_TX_FIR_C0), CTC_AT_DKIT_SERDES_REG_LANE, &param_unsigned_value);
            break;
        case DKIT_AT112G_TXEQ_EM_PRE2:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ANA_TX_FIR_C1), CTC_AT_DKIT_SERDES_REG_LANE, &param_unsigned_value);
            break;
        case DKIT_AT112G_TXEQ_EM_PRE:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ANA_TX_FIR_C2), CTC_AT_DKIT_SERDES_REG_LANE, &param_unsigned_value);
            break;
        case DKIT_AT112G_TXEQ_EM_MAIN:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ANA_TX_FIR_C3), CTC_AT_DKIT_SERDES_REG_LANE, &param_unsigned_value);
            break;
        case DKIT_AT112G_TXEQ_EM_POST:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ANA_TX_FIR_C4), CTC_AT_DKIT_SERDES_REG_LANE, &param_unsigned_value);
            break;
        case DKIT_AT112G_TXEQ_EM_POST2:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ANA_TX_FIR_C5), CTC_AT_DKIT_SERDES_REG_LANE, &param_unsigned_value);
            break;
        default:
            break;
    }

    /* Get Polarity */
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_FIR_POL), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    param_sign = ((data >> param) & 0x1) == 0 ? /* normal */ -1 : /* inverted */ 1;

    *p_value = param_sign * param_unsigned_value;
}


void
_ctc_at_dkit_get_txeq_param(ctc_at_dkit_serdes_dev_t* p_dev, void* ffe_param)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _dkit_at_serdes_56g_ffe_tap_t* p_ffe_tap = (_dkit_at_serdes_56g_ffe_tap_t*) ffe_param;
        _ctc_at_dkit_56g_get_txeq_param(p_dev, DKIT_AT56G_TXEQ_EM_PRE3, &p_ffe_tap->tap[0]);
        _ctc_at_dkit_56g_get_txeq_param(p_dev, DKIT_AT56G_TXEQ_EM_PRE2, &p_ffe_tap->tap[1]);
        _ctc_at_dkit_56g_get_txeq_param(p_dev, DKIT_AT56G_TXEQ_EM_PRE , &p_ffe_tap->tap[2]);
        _ctc_at_dkit_56g_get_txeq_param(p_dev, DKIT_AT56G_TXEQ_EM_MAIN, &p_ffe_tap->tap[3]);
        _ctc_at_dkit_56g_get_txeq_param(p_dev, DKIT_AT56G_TXEQ_EM_POST, &p_ffe_tap->tap[4]);
        _ctc_at_dkit_56g_get_txeq_param(p_dev, DKIT_AT56G_TXEQ_EM_NA  , &p_ffe_tap->tap[5]);
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _dkit_at_serdes_112g_ffe_tap_t* p_ffe_tap = (_dkit_at_serdes_112g_ffe_tap_t*)ffe_param;
        _ctc_at_dkit_112g_get_txeq_param(p_dev, DKIT_AT112G_TXEQ_EM_PRE3,    &p_ffe_tap->tap[0]);
        _ctc_at_dkit_112g_get_txeq_param(p_dev, DKIT_AT112G_TXEQ_EM_PRE2,    &p_ffe_tap->tap[1]);
        _ctc_at_dkit_112g_get_txeq_param(p_dev, DKIT_AT112G_TXEQ_EM_PRE,     &p_ffe_tap->tap[2]);
        _ctc_at_dkit_112g_get_txeq_param(p_dev, DKIT_AT112G_TXEQ_EM_MAIN,    &p_ffe_tap->tap[3]);
        _ctc_at_dkit_112g_get_txeq_param(p_dev, DKIT_AT112G_TXEQ_EM_POST,    &p_ffe_tap->tap[4]);
        _ctc_at_dkit_112g_get_txeq_param(p_dev, DKIT_AT112G_TXEQ_EM_POST2,   &p_ffe_tap->tap[5]);
    }
    
    
}

int32 
_ctc_at_dkit_56g_get_ctle_param(ctc_at_dkit_serdes_dev_t* p_dev, uint8 param, uint32* param_value)
{
    uint32 graycode;

    switch (param)
    {
        case DKIT_AT56G_CTLE_CUR1_SEL:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CURRENT1_SEL), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT56G_CTLE_RL1_SEL:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RL1_SEL), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT56G_CTLE_RL1_EXTRA:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RL1_EXTRA), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT56G_CTLE_RES1_SEL: 
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RES1_SEL), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT56G_CTLE_CAP1_SEL:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CAP1_SEL_G), CTC_AT_DKIT_SERDES_REG_LANE, &graycode);
            *param_value = _ctc_at_dkit_convert_graycode_to_u32(graycode);
            break;
        case DKIT_AT56G_CTLE_EN_MIDFREQ:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_EN_MID_FREQ), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT56G_CTLE_CS1_MID:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CS1_MID), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT56G_CTLE_RS1_MID:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RS1_MID), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT56G_CTLE_CUR2_SEL:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CURRENT2_SEL), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT56G_CTLE_RL2_SEL:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RL2_SEL), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT56G_CTLE_RL2_TUNE_G:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RL2_TUNE_G), CTC_AT_DKIT_SERDES_REG_LANE, &graycode);
            *param_value = _ctc_at_dkit_convert_graycode_to_u32(graycode);
            break;
        case DKIT_AT56G_CTLE_RES2_SEL:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RES2_SEL), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT56G_CTLE_CAP2_SEL:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CAP2_SEL), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT56G_CTLE_CL1_SEL:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CTLE_CL1_SEL), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT56G_CTLE_CL2_SEL:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CTLE_CL2_SEL), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        default:
            return CLI_EOL; /* Unsupported parameter */
    }        
    
    return CLI_SUCCESS;
}

int32
_ctc_at_dkit_112g_get_ctle_param(ctc_at_dkit_serdes_dev_t* p_dev, uint8 param, uint32* param_value)
{
        
    switch (param)
    {
        case DKIT_AT112G_CTLE_TRAIN_R:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TRAIN_CTLE_R), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT112G_CTLE_TRAIN_C:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TRAIN_CTLE_C), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT112G_CTLE_TRAIN_GC:
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TRAIN_CTLE_GC), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        case DKIT_AT112G_CTLE_TRAIN_ATTEN:
             _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TRAIN_CTLE_ATTE), CTC_AT_DKIT_SERDES_REG_LANE, param_value);
            break;
        default:
            return CLI_EOL; /* Unsupported parameter */
    }


    return CLI_SUCCESS;
}

void
_ctc_at_dkit_get_ctle_param(ctc_at_dkit_serdes_dev_t* p_dev, void* ctle_param)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _dkit_at_serdes_56g_ctle_param_t* ctle_56g = (_dkit_at_serdes_56g_ctle_param_t*)ctle_param;
        sal_memset(ctle_56g, 0, sizeof(_dkit_at_serdes_56g_ctle_param_t));
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_CUR1_SEL   , &ctle_56g->dkit_ctle_cur1_sel  );
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_RL1_SEL    , &ctle_56g->dkit_ctle_rl1_sel   );
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_RL1_EXTRA  , &ctle_56g->dkit_ctle_rl1_extra );
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_RES1_SEL   , &ctle_56g->dkit_ctle_res1_sel  );
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_CAP1_SEL   , &ctle_56g->dkit_ctle_cap1_sel  );
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_EN_MIDFREQ , &ctle_56g->dkit_ctle_en_midfreq);
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_CS1_MID    , &ctle_56g->dkit_ctle_cs1_mid   );
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_RS1_MID    , &ctle_56g->dkit_ctle_rs1_mid   );
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_CUR2_SEL   , &ctle_56g->dkit_ctle_cur2_sel  );
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_RL2_SEL    , &ctle_56g->dkit_ctle_rl2_sel   );
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_RL2_TUNE_G , &ctle_56g->dkit_ctle_rl2_tune_g);
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_RES2_SEL   , &ctle_56g->dkit_ctle_res2_sel  );
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_CAP2_SEL   , &ctle_56g->dkit_ctle_cap2_sel  );
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_CL1_SEL    , &ctle_56g->dkit_ctle_cl1_sel   );
        (void)_ctc_at_dkit_56g_get_ctle_param(p_dev, DKIT_AT56G_CTLE_CL2_SEL    , &ctle_56g->dkit_ctle_cl2_sel   );
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _dkit_at_serdes_112g_ctle_param_t* ctle_112g = (_dkit_at_serdes_112g_ctle_param_t*)ctle_param;
        sal_memset(ctle_112g, 0, sizeof(_dkit_at_serdes_112g_ctle_param_t));
        (void)_ctc_at_dkit_112g_get_ctle_param(p_dev, DKIT_AT112G_CTLE_TRAIN_R      , &ctle_112g->dkit_ctle_r       );
        (void)_ctc_at_dkit_112g_get_ctle_param(p_dev, DKIT_AT112G_CTLE_TRAIN_C      , &ctle_112g->dkit_ctle_c       );
        (void)_ctc_at_dkit_112g_get_ctle_param(p_dev, DKIT_AT112G_CTLE_TRAIN_GC     , &ctle_112g->dkit_ctle_gc      );
        (void)_ctc_at_dkit_112g_get_ctle_param(p_dev, DKIT_AT112G_CTLE_TRAIN_ATTEN  , &ctle_112g->dkit_ctle_atten   );
    }
}

void 
_ctc_at_dkit_set_dfe_enable(ctc_at_dkit_serdes_dev_t* p_dev, uint32 enable)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_DFE_EN), CTC_AT_DKIT_SERDES_REG_LANE, enable);
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        /* current not support in api */
    }
}

void 
_ctc_at_dkit_get_dfe_enable(ctc_at_dkit_serdes_dev_t* p_dev, uint32* enable)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_DFE_EN), CTC_AT_DKIT_SERDES_REG_LANE, enable);
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        *enable = 0xffffffff;
    }
}


void
_ctc_at_dkit_get_power_pll(ctc_at_dkit_serdes_dev_t* p_dev, uint8 *state)
{
    uint16 data = 0;
    uint8 lane;

    lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
        case 0:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PU_PLL0, &data);
            break;
        case 1:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PU_PLL1, &data);
            break;
        case 2:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PU_PLL2, &data);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PU_PLL3, &data);
            break;
        }
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        switch (lane)
        {
        case 0:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PU_PLL0, &data);
            break;
        case 1:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PU_PLL1, &data);
            break;
        case 2:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PU_PLL2, &data);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PU_PLL3, &data);
            break;
        }
    }
    *state = (uint8)data;
    
}

void _ctc_at_dkit_get_power_txrx(ctc_at_dkit_serdes_dev_t* p_dev, uint8 dir, uint8 *state)
{
    uint16 data = 0;
    uint8 lane;
    
    lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        if(DKIT_AT_DIR_TX == dir)
        {
            switch (lane)
            {
            case 0:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PU_TX0, &data);
                break;
            case 1:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PU_TX1, &data);
                break;
            case 2:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PU_TX2, &data);
                break;
            case 3:
            default:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PU_TX3, &data);
                break;
            }
        }
        else if(DKIT_AT_DIR_RX == dir)
        {
            switch (lane)
            {
            case 0:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PU_RX0, &data);
                break;
            case 1:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PU_RX1, &data);
                break;
            case 2:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PU_RX2, &data);
                break;
            case 3:
            default:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PU_RX3, &data);
                break;
            }
        }
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        if(DKIT_AT_DIR_TX == dir)
        {
            switch (lane)
            {
            case 0:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PU_TX0, &data);
                break;
            case 1:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PU_TX1, &data);
                break;
            case 2:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PU_TX2, &data);
                break;
            case 3:
            default:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PU_TX3, &data);
                break;
            }
        }
        else if(DKIT_AT_DIR_RX == dir)
        {
            switch (lane)
            {
            case 0:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PU_RX0, &data);
                break;
            case 1:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PU_RX1, &data);
                break;
            case 2:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PU_RX2, &data);
                break;
            case 3:
            default:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PU_RX3, &data);
                break;
            }
        }
    }
    *state = (uint8)data;

    
}

void _ctc_at_dkit_get_ref_freq(ctc_at_dkit_serdes_dev_t* p_dev, uint16* txfreq, uint16* rxfreq, uint16* txclksel, uint16* rxclksel)
{
    uint8 lane;
    
    lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
        case 0:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFFREF_TX0, txfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFFREF_RX0, rxfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFCLK_TX0, txclksel);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFCLK_RX0, rxclksel);
            break;
        case 1:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFFREF_TX1, txfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFFREF_RX1, rxfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFCLK_TX1, txclksel);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFCLK_RX1, rxclksel);
            break;
        case 2:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFFREF_TX2, txfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFFREF_RX2, rxfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFCLK_TX2, txclksel);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFCLK_RX2, rxclksel);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFFREF_TX3, txfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFFREF_RX3, rxfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFCLK_TX3, txclksel);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_REFCLK_RX3, rxclksel);
            break;
        }
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        switch (lane)
        {
        case 0:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REF_FREF_TX0, txfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REF_FREF_RX0, rxfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REFCLK_TX0, txclksel);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REFCLK_RX0, rxclksel);
            break;
        case 1:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REF_FREF_TX1, txfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REF_FREF_RX1, rxfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REFCLK_TX1, txclksel);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REFCLK_RX1, rxclksel);
            break;
        case 2:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REF_FREF_TX2, txfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REF_FREF_RX2, rxfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REFCLK_TX2, txclksel);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REFCLK_RX2, rxclksel);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REF_FREF_TX3, txfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REF_FREF_RX3, rxfreq);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REFCLK_TX3, txclksel);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_REFCLK_RX3, rxclksel);
            break;
        }
    }
    
}

static uint32 _ctc_at_dkit_speed_gbps_to_mbps(ctc_at_dkit_serdes_dev_t* p_dev, uint8 speed, uint32* mbps)
{
    *mbps = 0;

    if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        switch (speed)
        {
            case DKIT_AT112G_SERDES_1P0625G:         /* 1.0625 Gbps */
                *mbps = 1062;
                break;
            case DKIT_AT112G_SERDES_1P2288G:         /* 1.2288 Gbps */
                *mbps = 1228;
                break;
            case DKIT_AT112G_SERDES_1P25G:           /* 1.25 Gbps */
                *mbps = 1250;
                break;
            case DKIT_AT112G_SERDES_2P125G:          /* 2.125 Gbps */
                *mbps = 2125;
                break;
            case DKIT_AT112G_SERDES_2P4576G:         /* 2.4576 Gbps */
                *mbps = 2457;
                break;
            case DKIT_AT112G_SERDES_2P5G:            /* 2.5 Gbps */
                *mbps = 2500;
                break;
            case DKIT_AT112G_SERDES_2P578125G:       /* 2.578125 Gbps */
                *mbps = 2578;
                break;
            case DKIT_AT112G_SERDES_3P125G:          /* 3.125 Gbps */
                *mbps = 3125;
                break;
            case DKIT_AT112G_SERDES_4P25G:           /* 4.25 Gbps */
                *mbps = 4250;
                break;
            case DKIT_AT112G_SERDES_4P9152G:         /* 4.9152 Gbps */
                *mbps = 4915;
                break;
            case DKIT_AT112G_SERDES_5G:              /* 5.0 Gbps */
                *mbps = 5000;
                break;
            case DKIT_AT112G_SERDES_5P15625G:        /* 5.15625 Gbps */
                *mbps = 5156;
                break;
            case DKIT_AT112G_SERDES_6P144G:          /* 6.144 Gbps */
                *mbps = 6144;
                break;
            case DKIT_AT112G_SERDES_6P25G:           /* 6.25 Gbps */
                *mbps = 6250;
                break;
            case DKIT_AT112G_SERDES_7P5G:            /* 7.5 Gbps */
                *mbps = 7500;
                break;
            case DKIT_AT112G_SERDES_8P5G:            /* 8.5 Gbps */
                *mbps = 8500;
                break;
            case DKIT_AT112G_SERDES_9P8304G:         /* 9.8304 Gbps */
                *mbps = 9830;
                break;
            case DKIT_AT112G_SERDES_10P137G:         /* 10.137 Gbps */
                *mbps = 10137;
                break;
            case DKIT_AT112G_SERDES_10P3125G:        /* 10.3125 Gbps */
                *mbps = 10312;
                break;
            case DKIT_AT112G_SERDES_10P51875G:       /* 10.51875 Gbps */
                *mbps = 10518;
                break;
            case DKIT_AT112G_SERDES_10P9375G:     /* 10.9375 Gbps */
                *mbps = 10937;
                break;
            case DKIT_AT112G_SERDES_11P40625G:    /* 11.40625 Gbps */
                *mbps = 11406;
                break;
            case DKIT_AT112G_SERDES_12P16512G:       /* 12.16512 Gbps */
                *mbps = 12165;
                break;
            case DKIT_AT112G_SERDES_12P1875G:        /* 12.1875 Gbps */
                *mbps = 12187;
                break;
            case DKIT_AT112G_SERDES_12P5G:           /* 12.5 Gbps */
                *mbps = 12500;
                break;
            case DKIT_AT112G_SERDES_12P8906G:        /* 12.8906 Gbps */
                *mbps = 12890;
                break;
            case DKIT_AT112G_SERDES_12P96875G:    /* 12.96875 Gbps */
                *mbps = 12968;
                break;
            case DKIT_AT112G_SERDES_14P025G:         /* 14.025 Gbps */
                *mbps = 14025;
                break;
            case DKIT_AT112G_SERDES_15G:             /* 15.0 Gbps */
                *mbps = 15000;
                break;
            case DKIT_AT112G_SERDES_20P625G:         /* 20.625 Gbps */
                *mbps = 20625;
                break;
            case DKIT_AT112G_SERDES_24P33024G:       /* 24.33024 Gbps */
                *mbps = 24330;
                break;
            case DKIT_AT112G_SERDES_25P78125G:       /* 25.78125 Gbps */
                *mbps = 25781;
                break;
            case DKIT_AT112G_SERDES_26P5625G:        /* 26.5625 Gbps */
                *mbps = 26562;
                break;
            case DKIT_AT112G_SERDES_27P1875G:        /* 27.1875 Gbps */
                *mbps = 27187;
                break;
            case DKIT_AT112G_SERDES_27P34375G:    /* 27.34375 Gbps */
                *mbps = 27343;
                break;
            case DKIT_AT112G_SERDES_27P5G:           /* 27.5 Gbps */
                *mbps = 27500;
                break;
            case DKIT_AT112G_SERDES_27P78125G:    /* 27.78125 Gbps */
                *mbps = 27781;
                break;
            case DKIT_AT112G_SERDES_28P05G:          /* 28.05 Gbps */
                *mbps = 28050;
                break;
            case DKIT_AT112G_SERDES_28P125G:         /* 28.125 Gbps */
                *mbps = 28125;
                break;
            case DKIT_AT112G_SERDES_32P5G:           /* 32.5 Gbps */
                *mbps = 32500;
                break;
            case DKIT_AT112G_SERDES_46P25G:          /* 46.25 Gbps */
                *mbps = 46250;
                break;
            case DKIT_AT112G_SERDES_50G:             /* 50.0 Gbps */
                *mbps = 50000;
                break;
            case DKIT_AT112G_SERDES_51P5625G:        /* 51.5625 Gbps */
                *mbps = 51562;
                break;
            case DKIT_AT112G_SERDES_53P125G:         /* 53.125 Gbps */
                *mbps = 53125;
                break;
            case DKIT_AT112G_SERDES_56G:             /* 56.0 Gbps */
                *mbps = 56000;
                break;
            case DKIT_AT112G_SERDES_56P1G:           /* 56.1 Gbps */
                *mbps = 56100;
                break;
            case DKIT_AT112G_SERDES_56P25G:          /* 56.25 Gbps */
                *mbps = 56250;
                break;
            case DKIT_AT112G_SERDES_106GP25G:        /* 106.25 Gbps */
                *mbps = 106250;
                break;
            case DKIT_AT112G_SERDES_112G:            /* 112.0 Gbps */
                *mbps = 112000;
                break;
            case DKIT_AT112G_SERDES_112P5G:          /* 112.5 Gbps */
                *mbps = 112500;
                break;
            default:
                return CLI_EOL;
        }  
    }
   else if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
   {
        switch (speed)
        {
            case DKIT_AT56G_SERDES_1P0625G:        /* 1.0625 Gbps */
                *mbps = 1062;
                break;
            case DKIT_AT56G_SERDES_1P2288G:        /* 1.2288 Gbps */
                *mbps = 1228;
                break;
            case DKIT_AT56G_SERDES_1P25G:          /* 1.25 Gbps */
                *mbps = 1250;
                break;
            case DKIT_AT56G_SERDES_2P02752G:       /* 2.02752 Gbps */
                *mbps = 2027;
                break;
            case DKIT_AT56G_SERDES_2P125G:         /* 2.125 Gbps */
                *mbps = 2125;
                break;
            case DKIT_AT56G_SERDES_2P4576G:        /* 2.4576 Gbps */
                *mbps = 2457;
                break;
            case DKIT_AT56G_SERDES_2P5G:           /* 2.5 Gbps */
                *mbps = 2500;
                break;
            case DKIT_AT56G_SERDES_2P57812G:       /* 2.578125 Gbps */
                *mbps = 2578;
                break;
            case DKIT_AT56G_SERDES_3P072G:         /* 3.072 Gbps */
                *mbps = 3072;
                break;
            case DKIT_AT56G_SERDES_3P125G:         /* 3.125 Gbps */
                *mbps = 3125;
                break;
            case DKIT_AT56G_SERDES_4P08804G:       /* 4.08804 Gbps */
                *mbps = 4088;
                break;
            case DKIT_AT56G_SERDES_4P25G:          /* 4.25 Gbps */
                *mbps = 4250;
                break;
            case DKIT_AT56G_SERDES_4P9152G:        /* 4.9152 Gbps */
                *mbps = 4915;
                break;
            case DKIT_AT56G_SERDES_5G:            /* 5.0 Gbps */
                *mbps = 5000;
                break;
            case DKIT_AT56G_SERDES_5P15625G:       /* 5.15625 Gbps */
                *mbps = 5156;
                break;
            case DKIT_AT56G_SERDES_6P144G:         /* 6.144 Gbps */
                *mbps = 6144;
                break;
            case DKIT_AT56G_SERDES_6P25G:          /* 6.25 Gbps */
                *mbps = 6250;
                break;
            case DKIT_AT56G_SERDES_7P3728G:        /* 7.3728 Gbps */
                *mbps = 7372;
                break;
            case DKIT_AT56G_SERDES_7P5G:           /* 7.5 Gbps */
                *mbps = 7500;
                break;
            case DKIT_AT56G_SERDES_8P11008G:       /* 8.11008 Gbps */
                *mbps = 8110;
                break;
            case DKIT_AT56G_SERDES_8P5G:           /* 8.5 Gbps */
                *mbps = 8500;
                break;
            case DKIT_AT56G_SERDES_9P8304G:        /* 9.8304 Gbps */
                *mbps = 9830;
                break;
            case DKIT_AT56G_SERDES_10G:            /* 10.0 Gbps */
                *mbps = 10000;
                break;
            case DKIT_AT56G_SERDES_10P137G:        /* 10.137 Gbps */
                *mbps = 10137;
                break;
            case DKIT_AT56G_SERDES_10P3125G:       /* 10.3125 Gbps */
                *mbps = 10312;
                break;
            case DKIT_AT56G_SERDES_10P5187G:       /* 10.51875 Gbps */
                *mbps = 10518;
                break;
            case DKIT_AT56G_SERDES_12P1651G:       /* 12.16512 Gbps */
                *mbps = 12165;
                break;
            case DKIT_AT56G_SERDES_12P1875G:       /* 12.1875 Gbps */
                *mbps = 12187;
                break;
            case DKIT_AT56G_SERDES_12P288G:        /* 12.288 Gbps */
                *mbps = 12288;
                break;
            case DKIT_AT56G_SERDES_12P5G:          /* 12.5 Gbps */
                *mbps = 12500;
                break;
            case DKIT_AT56G_SERDES_12P8906G:       /* 12.8906 Gbps */
                *mbps = 12890;
                break;
            case DKIT_AT56G_SERDES_14P025G:        /* 14.025 Gbps */
                *mbps = 14025;
                break;
            case DKIT_AT56G_SERDES_14P7456G:       /* 14.7456 Gbps */
                *mbps = 14745;
                break;
            case DKIT_AT56G_SERDES_15G:            /* 15.0 Gbps */
                *mbps = 15000;
                break;
            case DKIT_AT56G_SERDES_16P2201G:       /* 16.22016 Gbps */
                *mbps = 16220;
                break;
            case DKIT_AT56G_SERDES_19P6608G:       /* 19.6608 Gbps */
                *mbps = 19660;
                break;
            case DKIT_AT56G_SERDES_20P625G:        /* 20.625 Gbps */
                *mbps = 20625;
                break;
            case DKIT_AT56G_SERDES_24P3302G:       /* 24.33024 Gbps */
                *mbps = 24330;
                break;
            case DKIT_AT56G_SERDES_25P7812G:       /* 25.78125 Gbps */
                *mbps = 25781;
                break;
            case DKIT_AT56G_SERDES_26P5625G:       /* 26.5625 Gbps */
                *mbps = 26562;
                break;
            case DKIT_AT56G_SERDES_275G:           /* 27.5 Gbps */
                *mbps = 27500;
                break;
            case DKIT_AT56G_SERDES_28P05G:         /* 28.05 Gbps */
                *mbps = 28050;
                break;
            case DKIT_AT56G_SERDES_28P125G:        /* 28.125 Gbps */
                *mbps = 28125;
                break;
            case DKIT_AT56G_SERDES_32G:            /* 32.0 Gbps */
                *mbps = 32000;
                break;
            case DKIT_AT56G_SERDES_46P25G:         /* 46.25 Gbps */
                *mbps = 46250;
                break;
            case DKIT_AT56G_SERDES_51P5625G:       /* 51.5625 Gbps */
                *mbps = 51562;
                break;
            case DKIT_AT56G_SERDES_53P125G:        /* 53.125 Gbps */
                *mbps = 53125;
                break;
            case DKIT_AT56G_SERDES_56G:            /* 56.0 Gbps */
                *mbps = 56000;
                break;
            case DKIT_AT56G_SERDES_56P1G:          /* 56.1 Gbps */
                *mbps = 56100;
                break;
            case DKIT_AT56G_SERDES_56P25G:         /* 56.25 Gbps */
                *mbps = 56250;
                break;
            case DKIT_AT56G_SERDES_64G:            /* 64.0 Gbps */
                *mbps = 64000;
                break;
            default:
                return CLI_EOL;
        }
    
   }

   return CLI_SUCCESS;
}

void _ctc_at_dkit_get_txrx_rate(ctc_at_dkit_serdes_dev_t* p_dev, uint8* tx_speed, uint8* rx_speed)
{
    uint8 lane;
    uint16 tx_data = 0;
    uint16 rx_data = 0;

    lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);

    if(CTC_AT_DKIT_SERDES_112G== p_dev->type)
    {
        switch (lane)
       {
        case 0:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_TX0, &tx_data);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_RX0, &rx_data);
            break;
        case 1:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_TX1, &tx_data);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_RX1, &rx_data);
            break;
        case 2:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_TX2, &tx_data);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_RX2, &rx_data);
            break;
        case 3:
        default:    
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_TX3, &tx_data);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_RX3, &rx_data);
            break;
       }    
    }
    else if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch (lane)
       {
        case 0:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_TX0, &tx_data);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_RX0, &rx_data);
            break;
        case 1:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_TX1, &tx_data);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_RX1, &rx_data);
            break;
        case 2:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_TX2, &tx_data);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_RX2, &rx_data);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_TX3, &tx_data);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_RX3, &rx_data);
            break;
       }
    }

    *tx_speed = (uint8)tx_data;
    *rx_speed = (uint8)rx_data;
    
    
}

void _ctc_at_dkit_get_data_width(ctc_at_dkit_serdes_dev_t* p_dev, uint16* txwidth, uint16* rxwidth)
{
    uint32 txDataSelBits, txDataPAM2En, rxDataSelBits, rxDataPAM2En, txdata, rxdata;
    uint8  txspeed,rxspeed;
    uint32 tx_mbps,rx_mbps;

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_SEL_BITS), CTC_AT_DKIT_SERDES_REG_LANE, &txDataSelBits);
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_PAM2_EN), CTC_AT_DKIT_SERDES_REG_LANE, &txDataPAM2En);
        if (0 == txDataPAM2En)
        {
            if (0 == txDataSelBits)
                *txwidth = DKIT_AT56G_DATABUS_80BIT;
            else
                *txwidth = DKIT_AT56G_DATABUS_64BIT;
        }
        else
        {
            if (0 == txDataSelBits)
                *txwidth = DKIT_AT56G_DATABUS_40BIT;
            else
                *txwidth = DKIT_AT56G_DATABUS_32BIT;
        }

        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_SEL_BITS), CTC_AT_DKIT_SERDES_REG_LANE, &rxDataSelBits);
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_PAM2_EN), CTC_AT_DKIT_SERDES_REG_LANE, &rxDataPAM2En);
        if (0 == rxDataPAM2En)
        {
            if (0 == rxDataSelBits)
                *rxwidth = DKIT_AT56G_DATABUS_80BIT;
            else
                *rxwidth = DKIT_AT56G_DATABUS_64BIT;
        }
        else
        {
            if (0 == rxDataSelBits)
                *rxwidth = DKIT_AT56G_DATABUS_40BIT;
            else
                *rxwidth = DKIT_AT56G_DATABUS_32BIT;
        }
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_SEL_BITS), CTC_AT_DKIT_SERDES_REG_LANE, &txdata);
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_SEL_BITS), CTC_AT_DKIT_SERDES_REG_LANE, &rxdata);
        _ctc_at_dkit_get_txrx_rate(p_dev, &txspeed, &rxspeed);
        (void)_ctc_at_dkit_speed_gbps_to_mbps(p_dev,txspeed, &tx_mbps);
        (void)_ctc_at_dkit_speed_gbps_to_mbps(p_dev,rxspeed, &rx_mbps);
        if (tx_mbps > 56250)         /* speed > 56.25 Gbps */
        {
            *txwidth = (0 == txdata) ? DKIT_AT112G_DATABUS_160BIT : DKIT_AT112G_DATABUS_128BIT;
        }
        else if (tx_mbps > 32000)    /* speed > 32.0 Gbps */
        {
            *txwidth = (0 == txdata) ? DKIT_AT112G_DATABUS_80BIT : DKIT_AT112G_DATABUS_64BIT;
        }
        else if (tx_mbps > 0)        /* speed > 0.0 Gbps */
        {
            *txwidth = (0 == txdata) ? DKIT_AT112G_DATABUS_40BIT : DKIT_AT112G_DATABUS_32BIT;
        }
        
        if (rx_mbps > 56250)         /* speed > 56.25Gbps */
        {
            *rxwidth = (0 == rxdata) ? DKIT_AT112G_DATABUS_160BIT : DKIT_AT112G_DATABUS_128BIT;
        }
        else if (rx_mbps > 32000)    /* speed > 32Gbps */
        {
            *rxwidth = (0 == rxdata) ? DKIT_AT112G_DATABUS_80BIT : DKIT_AT112G_DATABUS_64BIT;
        }
        else if (rx_mbps > 0)        /* speed > 0Gbps */
        {
            *rxwidth = (0 == rxdata) ? DKIT_AT112G_DATABUS_40BIT : DKIT_AT112G_DATABUS_32BIT;
        }
    }
}

void _ctc_at_dkit_get_mcu_freq(ctc_at_dkit_serdes_dev_t* p_dev, uint16* freq_mhz)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_MCU_CLK, freq_mhz);
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_MCU_CLK, freq_mhz);
    }
    
}

void _ctc_at_dkit_set_tx_en(ctc_at_dkit_serdes_dev_t* p_dev, uint16 state)
{
    uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
       switch (lane)
       {
        case 0:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_IDLE0, state ? 0 : 1);
            break;
        case 1:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_IDLE1, state ? 0 : 1);
            break;
        case 2:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_IDLE2, state ? 0 : 1);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_IDLE3, state ? 0 : 1);
            break;
       }  
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
       switch (lane)
       {
        case 0:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_IDLE0, state ? 0 : 1);
            break;
        case 1:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_IDLE1, state ? 0 : 1);
            break;
        case 2:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_IDLE2, state ? 0 : 1);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_IDLE3, state ? 0 : 1);
            break;
       } 
    }
    
    
}

void _ctc_at_dkit_get_tx_en(ctc_at_dkit_serdes_dev_t* p_dev, uint8* state)
{
    uint16 value = 0;
    uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
       switch (lane)
       {
        case 0:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_IDLE0, &value);
            break;
        case 1:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_IDLE1, &value);
            break;
        case 2:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_IDLE2, &value);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_IDLE3, &value);
            break;
       }  
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
       switch (lane)
       {
        case 0:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_IDLE0, &value);
            break;
        case 1:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_IDLE1, &value);
            break;
        case 2:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_IDLE2, &value);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_IDLE3, &value);
            break;
       } 
    }

    *state = (0 == value) ? 1 : 0;
    
    
}

void _ctc_at_dkit_get_power_ivref(ctc_at_dkit_serdes_dev_t* p_dev, uint8* state)
{
    uint16 value = DKIT_AT_USELESS_ID16;
    
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_PU_IVREF, &value);
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
       _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_PU_IVREF, &value);
    }

    *state =(uint8)value;
    
    
}

void _ctc_at_dkit_get_sq_det(ctc_at_dkit_serdes_dev_t* p_dev, uint8* state)
{
    uint16 value = 0;
    uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
       switch (lane)
       {
        case 0:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_SQ_DET_LPF0, &value);
            break;
        case 1:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_SQ_DET_LPF1, &value);
            break;
        case 2:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_SQ_DET_LPF2, &value);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_SQ_DET_LPF3, &value);
            break;
       }  
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
       switch (lane)
       {
        case 0:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_SQ_DET_LPF0, &value);
            break;
        case 1:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_SQ_DET_LPF1, &value);
            break;
        case 2:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_SQ_DET_LPF2, &value);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_SQ_DET_LPF3, &value);
            break;
       } 
    }

    *state =(uint8)value;
    
    
}

void _ctc_at_dkit_set_sq_thrd(ctc_at_dkit_serdes_dev_t* p_dev, uint16 threshold)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_SQ_INDV), CTC_AT_DKIT_SERDES_REG_LANE, 1);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_SQ_RES_EXT), CTC_AT_DKIT_SERDES_REG_LANE, threshold + 0x20);
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_SQ_INDV_EXT_EN), CTC_AT_DKIT_SERDES_REG_LANE, 1);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_SQ_RES_EXT), CTC_AT_DKIT_SERDES_REG_LANE, threshold + 0x20);
    }    
}

void _ctc_at_dkit_get_sq_thrd(ctc_at_dkit_serdes_dev_t* p_dev, uint16* threshold)
{
    uint32 value;
    
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_SQ_RES_RD), CTC_AT_DKIT_SERDES_REG_LANE, &value);
        *threshold = (uint16)value - 0x20;
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_SQ_RES_RD), CTC_AT_DKIT_SERDES_REG_LANE, &value);
        *threshold = (uint16)value - 0x20;
    }
}

/*far-end loopback*/
void
_ctc_at_dkit_serdes_get_loopback_external(ctc_at_dkit_serdes_dev_t* p_dev, uint32* p_en)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_D_RX2TX_LPBK), CTC_AT_DKIT_SERDES_REG_LANE, p_en);
    }
    else
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DIG_RX2TX_LPBK), CTC_AT_DKIT_SERDES_REG_LANE, p_en);
    }
    
}

/*Local analog serial loopback*/
void
_ctc_at_dkit_serdes_get_loopback_local(ctc_at_dkit_serdes_dev_t* p_dev, uint32* p_en)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_A_TX2RX_LPBK), CTC_AT_DKIT_SERDES_REG_LANE, p_en);
    }
    else
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ANA_TX2RX_LPBK), CTC_AT_DKIT_SERDES_REG_LANE, p_en);
    }
    
}

void
_ctc_at_dkit_serdes_get_loopback_internal(ctc_at_dkit_serdes_dev_t* p_dev, uint32* p_en)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_D_TX2RX_LPBK), CTC_AT_DKIT_SERDES_REG_LANE, p_en);
    }
    else
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DIG_TX2RX_LPBK), CTC_AT_DKIT_SERDES_REG_LANE, p_en);
    }
    
}

int32 _ctc_at_dkit_wait_pllready(ctc_at_dkit_serdes_dev_t* p_dev)
{

    uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
            case 0:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_RX0, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_TX0, 1);
                break;
            case 1:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_RX1, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_TX1, 1);
                break;
            case 2:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_RX2, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_TX2, 1);
                break;
            case 3:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_RX3, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_PLL_RDY_TX3, 1);
                break;
            default:
                return CLI_EOL;
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_RX0, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_TX0, 1);
                break;
            case 1:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_RX1, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_TX1, 1);
                break;
            case 2:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_RX2, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_TX2, 1);
                break;
            case 3:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_RX3, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_PLL_RDY_TX3, 1);
                break;
            default:
                return CLI_EOL; 
        }
    }

    return CLI_SUCCESS;
}

void
_ctc_at_dkit_serdes_get_loopback(ctc_at_dkit_serdes_dev_t* p_dev, uint8 mode, uint8* enable)
{
    uint32 en = 0;
        
    switch(mode)
    {
        case DKIT_AT_LOOPBACK_INTERNAL: /* Internal Loopback */
            _ctc_at_dkit_serdes_get_loopback_internal(p_dev, &en);
            break;
        case DKIT_AT_LOOPBACK_EXTERNAL: /* External Loopback */
            _ctc_at_dkit_serdes_get_loopback_external(p_dev, &en);
            break;
        case DKIT_AT_LOOPBACK_LOCAL_ANALOG: /* Local analog serial loopback */
            _ctc_at_dkit_serdes_get_loopback_local(p_dev, &en);
            break;       
        default:
            break;
    }
    *enable =(uint8)en;
}

void _ctc_at_dkit_get_temperature(ctc_at_dkit_serdes_dev_t* p_dev, uint32* temperature)
{
    uint32 value;
    int32 codevalue;

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TSEN_DATA), CTC_AT_DKIT_SERDES_REG_GRP, &value);
        codevalue = _ctc_at_dkit_convert_twos_complement_to_i32(value, 12);
        *temperature = (int32)((codevalue * DKIT_AT56G_TSENE_GAIN) + DKIT_AT56G_TSENE_OFFSET);
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TSEN_ADC_DATA), CTC_AT_DKIT_SERDES_REG_GRP, &value);
        codevalue = _ctc_at_dkit_convert_twos_complement_to_i32(value, 12);
        *temperature = (int32)((codevalue * DKIT_AT112G_TSENE_GAIN) + DKIT_AT112G_TSENE_OFFSET);
    }
}

void _ctc_at_dkit_get_msb_lsb_swap(ctc_at_dkit_serdes_dev_t* p_dev, uint8* tx_swap, uint8* rx_swap)
{
    uint32 txDSwapData, txDataSwapData, rxDSwapData, rxDataSwapData;

    if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TXD_SWAP), CTC_AT_DKIT_SERDES_REG_LANE, &txDSwapData);
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TXDATA_SWAP), CTC_AT_DKIT_SERDES_REG_LANE, &txDataSwapData);
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RXD_SWAP), CTC_AT_DKIT_SERDES_REG_LANE, &rxDSwapData);
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RXDATA_SWAP), CTC_AT_DKIT_SERDES_REG_LANE, &rxDataSwapData);

        /* TX Pattern */
        if ((0 == txDataSwapData) && (0 == txDSwapData))
        {
            *tx_swap = DKIT_AT112G_SWAP_DISABLE;
        }
        else if ((1 == txDataSwapData) && (0 == txDSwapData))
        {
            *tx_swap = DKIT_AT112G_SWAP_PRECODER;
        }
        else if ((0 == txDataSwapData) && (1 == txDSwapData))
        {
            *tx_swap = DKIT_AT112G_SWAP_POSTCODER;
        }
        else
        {
            *tx_swap = DKIT_AT112G_SWAP_NOT_USED;
        }

        /* RX Pattern */
        if ((0 == rxDSwapData) && (0 == rxDataSwapData))
        {
            *rx_swap = DKIT_AT112G_SWAP_DISABLE;
        }
        else if ((1 == rxDataSwapData) && (0 == rxDSwapData))
        {
            *rx_swap = DKIT_AT112G_SWAP_PRECODER;
        }
        else if ((0 == rxDataSwapData) && (1 == rxDSwapData))
        {
            *rx_swap = DKIT_AT112G_SWAP_POSTCODER;
        }
        else
        {
            *rx_swap = DKIT_AT112G_SWAP_NOT_USED;
        }    
    }
    else if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TXD_SWAP), CTC_AT_DKIT_SERDES_REG_LANE, &txDSwapData);
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TXDATA_SWAP), CTC_AT_DKIT_SERDES_REG_LANE, &txDataSwapData);
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RXD_SWAP), CTC_AT_DKIT_SERDES_REG_LANE, &rxDSwapData);
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RXDATA_SWAP), CTC_AT_DKIT_SERDES_REG_LANE, &rxDataSwapData);
        
        if ((0 == txDataSwapData) && (0 == txDSwapData))
        {
            *tx_swap = DKIT_AT56G_SWAP_DISABLE;
        }
        else if ((1 == txDataSwapData) && (0 == txDSwapData))
        {
            *tx_swap = DKIT_AT56G_SWAP_PRECODER;
        }
        else if ((0 == txDataSwapData) && (1 == txDSwapData))
        {
            *tx_swap = DKIT_AT56G_SWAP_POSTCODER;
        }
        else
        {
            *tx_swap = DKIT_AT56G_SWAP_NOT_USED;
        }

        /* RX Pattern */
        if ((0 == rxDSwapData) && (0 == rxDataSwapData))
        {
            *rx_swap = DKIT_AT56G_SWAP_DISABLE;
        }
        else if ((1 == rxDataSwapData) && (0 == rxDSwapData))
        {
            *rx_swap = DKIT_AT56G_SWAP_PRECODER;
        }
        else if ((0 == rxDataSwapData) && (1 == rxDSwapData))
        {
            *rx_swap = DKIT_AT56G_SWAP_POSTCODER;
        }
        else
        {
            *rx_swap = DKIT_AT112G_SWAP_NOT_USED;
        }    
    }
}

void _ctc_at_dkit_set_graycode(ctc_at_dkit_serdes_dev_t* p_dev, uint8 tx_graycode, uint8 rx_graycode)
{
    uint16 txdata16 = tx_graycode;
    uint16 rxdata16 = rx_graycode;
    uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    
    if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_GRAYCODE_EN0, txdata16);
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_GRAYCODE_EN0, rxdata16);
                break;
            case 1:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_GRAYCODE_EN1, txdata16);
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_GRAYCODE_EN1, rxdata16);
                break;
            case 2:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_GRAYCODE_EN2, txdata16);
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_GRAYCODE_EN2, rxdata16);
                break;
            case 3:
            default:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_GRAYCODE_EN3, txdata16);
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_GRAYCODE_EN3, rxdata16);
                break;
       }
    }
    else if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_GRAYCODE_EN0, txdata16);
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_GRAYCODE_EN0, rxdata16);
                break;
            case 1:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_GRAYCODE_EN1, txdata16);
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_GRAYCODE_EN1, rxdata16);
                break;
            case 2:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_GRAYCODE_EN2, txdata16);
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_GRAYCODE_EN2, rxdata16);
                break;
            case 3:
            default:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_GRAYCODE_EN3, txdata16);
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_GRAYCODE_EN3, rxdata16);
                break;
       }
   }
}

void _ctc_at_dkit_set_precode(ctc_at_dkit_serdes_dev_t* p_dev, uint8 tx_precode, uint8 rx_precode)
{
     uint16 txdata16 = tx_precode;
     uint16 rxdata16 = rx_precode;
     uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
     
     if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
     {
         switch(lane)
         {
             case 0:
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_PRECODE_EN0, txdata16);
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_PRECODE_EN0, rxdata16);
                 break;
             case 1:
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_PRECODE_EN1, txdata16);
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_PRECODE_EN1, rxdata16);
                 break;
             case 2:
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_PRECODE_EN2, txdata16);
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_PRECODE_EN2, rxdata16);
                 break;
             case 3:
             default:
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_PRECODE_EN3, txdata16);
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_PRECODE_EN3, rxdata16);
                 break;
        }
     }
     else if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
     {
         switch(lane)
         {
             case 0:
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_PRECODE_EN0, txdata16);
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_PRECODE_EN0, rxdata16);
                 break;
             case 1:
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_PRECODE_EN1, txdata16);
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_PRECODE_EN1, rxdata16);
                 break;
             case 2:
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_PRECODE_EN2, txdata16);
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_PRECODE_EN2, rxdata16);
                 break;
             case 3:
             default:
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_PRECODE_EN3, txdata16);
                 _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_PRECODE_EN3, rxdata16);
                 break;
        }
    }
}

void _ctc_at_dkit_get_graycode(ctc_at_dkit_serdes_dev_t* p_dev, uint8* tx_graycode, uint8* rx_graycode)
{
    uint16 txdata16 = 0, rxdata16 = 0;
    uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    
    if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_GRAYCODE_EN0, &txdata16);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_GRAYCODE_EN0, &rxdata16);
                break;
            case 1:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_GRAYCODE_EN1, &txdata16);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_GRAYCODE_EN1, &rxdata16);
                break;
            case 2:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_GRAYCODE_EN2, &txdata16);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_GRAYCODE_EN2, &rxdata16);
                break;
            case 3:
            default:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_GRAYCODE_EN3, &txdata16);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_GRAYCODE_EN3, &rxdata16);
                break;
       }
    }
    else if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_GRAYCODE_EN0, &txdata16);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_GRAYCODE_EN0, &rxdata16);
                break;
            case 1:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_GRAYCODE_EN1, &txdata16);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_GRAYCODE_EN1, &rxdata16);
                break;
            case 2:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_GRAYCODE_EN2, &txdata16);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_GRAYCODE_EN2, &rxdata16);
                break;
            case 3:
            default:
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_GRAYCODE_EN3, &txdata16);
                _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_GRAYCODE_EN3, &rxdata16);
                break;
       }
   }
   *tx_graycode = (uint8)txdata16;
   *rx_graycode = (uint8)rxdata16;
}

void _ctc_at_dkit_get_precode(ctc_at_dkit_serdes_dev_t* p_dev, uint8* tx_precode, uint8* rx_precode)
{
     uint16 txdata16 = 0, rxdata16 = 0;
     uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
     
     if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
     {
         switch(lane)
         {
             case 0:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_PRECODE_EN0, &txdata16);
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_PRECODE_EN0, &rxdata16);
                 break;
             case 1:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_PRECODE_EN1, &txdata16);
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_PRECODE_EN1, &rxdata16);
                 break;
             case 2:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_PRECODE_EN2, &txdata16);
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_PRECODE_EN2, &rxdata16);
                 break;
             case 3:
             default:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_PRECODE_EN3, &txdata16);
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_PRECODE_EN3, &rxdata16);
                 break;
        }
     }
     else if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
     {
         switch(lane)
         {
             case 0:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_PRECODE_EN0, &txdata16);
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_PRECODE_EN0, &rxdata16);
                 break;
             case 1:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_PRECODE_EN1, &txdata16);
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_PRECODE_EN1, &rxdata16);
                 break;
             case 2:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_PRECODE_EN2, &txdata16);
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_PRECODE_EN2, &rxdata16);
                 break;
             case 3:
             default:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_PRECODE_EN3, &txdata16);
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_PRECODE_EN3, &rxdata16);
                 break;
        }
    }
    *tx_precode = (uint8)txdata16;
    *rx_precode = (uint8)rxdata16;
}

void _ctc_at_dkit_get_cdr_lock(ctc_at_dkit_serdes_dev_t* p_dev, uint8* lock, uint8* clamp)
{
     uint32 val_32;
     uint16 val_16;
     uint32 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);

     if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
     {
         _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_CDR_LOCK), CTC_AT_DKIT_SERDES_REG_LANE, &val_32);

         switch(lane)
         {
             case 0:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_DTL_CLAMP0, &val_16);
                 break;
             case 1:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_DTL_CLAMP1, &val_16);
                 break;
             case 2:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_DTL_CLAMP2, &val_16);
                 break;
             case 3:
             default:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_DTL_CLAMP3, &val_16);
                 break;
         }

        *lock  = (uint8)val_32;
        *clamp = (uint8)val_16; 
         
     }
     else
     {
        /* 56G not suppot check cdr lock*/
        *lock  = DKIT_AT_USELESS_ID8;

        switch(lane)
         {
             case 0:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_DTL_CLAMP0, &val_16);
                 break;
             case 1:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_DTL_CLAMP1, &val_16);
                 break;
             case 2:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_DTL_CLAMP2, &val_16);
                 break;
             case 3:
             default:
                 _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_DTL_CLAMP3, &val_16);
                 break;
         }

        *clamp = (uint8)val_16; 
     }
     
}

uint32 _ctc_at_dkit_convert_graycode_to_u32(uint32 graycode)
{
    graycode ^= graycode >> 16;
    graycode ^= graycode >> 8;
    graycode ^= graycode >> 4;
    graycode ^= graycode >> 2;
    graycode ^= graycode >> 1;
    return graycode;
}


int32 _ctc_at_dkit_convert_twos_complement_to_i32(uint32 tc, uint16 tcBits)
{
    uint32 inverted;
    int32 value;

    if ((tc >> (tcBits - 1)) == 0)
        return (int32)tc;
    else
    {
        inverted = (~tc) + 1;
        value = (int32)(inverted & ((1 << (tcBits - 1)) - 1));
        return -value;
    }
}

int32 _ctc_at_dkit_convert_signed_magnitude_to_i32(uint32 sm, uint16 sm_bits)
{
    if ((sm >> (sm_bits - 1)) == 0)
    {
        return (uint32) sm;
    }
    else
    {
        int32 value = (int32) (sm & ((1 << (sm_bits - 1)) - 1));
        return -value;
    }
}

void _ctc_at_dkit_convert_to_codes(ctc_at_dkit_serdes_dev_t* p_dev, _ctc_at_dkit_serdes_field_t* p_field, int32 *tap)
{
    uint32 code;

    _ctc_at_dkit_serdes_read_reg_field(p_dev, p_field, CTC_AT_DKIT_SERDES_REG_LANE, &code);
    *tap = _ctc_at_dkit_convert_twos_complement_to_i32(code, p_field->total_bits); /* Codes */
}

void _ctc_at_dkit_convert_to_millicodes(ctc_at_dkit_serdes_dev_t* p_dev, _ctc_at_dkit_serdes_field_t* p_field, int32 *tap)
{
    uint32 code;

    _ctc_at_dkit_serdes_read_reg_field(p_dev, p_field, CTC_AT_DKIT_SERDES_REG_LANE, &code);
    *tap = _ctc_at_dkit_convert_twos_complement_to_i32(code, p_field->total_bits) * 1000; /* milli-Codes */
}

void _ctc_at_dkit_convert_to_average_millicodes(ctc_at_dkit_serdes_dev_t* p_dev, _ctc_at_dkit_serdes_field_t* p_field_top,
                                                              _ctc_at_dkit_serdes_field_t* p_field_mid, _ctc_at_dkit_serdes_field_t* p_field_bot, int32* value)
{
    int32 top,mid,bot;

    _ctc_at_dkit_convert_to_millicodes(p_dev, p_field_top, &top);
    _ctc_at_dkit_convert_to_millicodes(p_dev, p_field_mid, &mid);
    _ctc_at_dkit_convert_to_millicodes(p_dev, p_field_bot, &bot);

    *value = (top + mid + bot) / 3;
}

void _ctc_at_dkit_convert_msblsb_to_millicodes(ctc_at_dkit_serdes_dev_t* p_dev, _ctc_at_dkit_serdes_field_t* p_field_msb, _ctc_at_dkit_serdes_field_t* p_field_lsb, int32* value)
{
    
    uint32 msbdata, lsbdata;
    int32  msb, lsb;

    _ctc_at_dkit_serdes_read_reg_field(p_dev, p_field_msb, CTC_AT_DKIT_SERDES_REG_LANE, &msbdata);
    _ctc_at_dkit_serdes_read_reg_field(p_dev, p_field_lsb, CTC_AT_DKIT_SERDES_REG_LANE, &lsbdata);
    msb = _ctc_at_dkit_convert_signed_magnitude_to_i32(msbdata, p_field_msb->total_bits);
    lsb = _ctc_at_dkit_convert_signed_magnitude_to_i32(lsbdata, p_field_lsb->total_bits);
    *value = (((msb * 2) + lsb) * 1000) / 3; /* milli-Codes */
}

void _ctc_at_dkit_get_data_acquisition_rate(ctc_at_dkit_serdes_dev_t* p_dev, uint8* acq_rate)
{
    uint32 value;
    
    if(CTC_AT_DKIT_SERDES_112G == p_dev->type) 
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_DATA_WIDTH), CTC_AT_DKIT_SERDES_REG_LANE, &value);
        switch (value)
        {
        case 1:
            *acq_rate = DKIT_AT112G_RATE_FULL;
            break;
        case 2:
            *acq_rate = DKIT_AT112G_RATE_HALF;
            break;
        case 3:
            *acq_rate = DKIT_AT112G_RATE_QUARTER;
            break;
        default:
            *acq_rate = DKIT_AT112G_RATE_UNKNOWN;
        }
            
    }
    else if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        *acq_rate = DKIT_AT_USELESS_ID8;
    }
}

#ifdef CTC_MATH_FLOATING
uint32 _ctc_at_dkit_eom_stats_get_amplitute_stat(ctc_at_dkit_serdes_dev_t* p_dev, double* bufferPtr, 
                                                uint32 phaseCenter, uint16 phaseMaxCount, uint32 voltageMin,
                                                uint32 voltageMax, uint32 voltageCenter, uint32 voltageMaxCount, 
                                                int32* eyeRawData, _dkit_at_eom_stats_eye_amp_t* amplitudeStats)
{
    double x_double, y_double, mean0, mean1, stdev0, stdev1, log;
    uint32 findHist[2] = { 0, 0 };
    uint32 vectorCount = voltageMax - voltageMin;
    uint32 i, j, adjustedVoltageCenter, findCount, segment0Min, segment0Max, segment1Min, segment1Max;
    segment1Min = 0;
    log = 0.0;

    amplitudeStats->Q = -1;
    amplitudeStats->SNR = -1;
    amplitudeStats->lowerMean = -1;
    amplitudeStats->lowerStdDev = -1;
    amplitudeStats->upperMean = -1;
    amplitudeStats->upperStdDev = -1;
    
    /*
    * Get amplitude data @ phase 0
    * Store data in buffer[0] relative to range where 0 is data at minimum phase (going forward all indices are relative, unless stated)
    * buffer[0] = [vertical]            buffer[1] = [unused]
    */
    i = 0;
    adjustedVoltageCenter = voltageCenter - voltageMin;
    for (j = voltageMin; j <= voltageMax; j++)
    {
        /* buffer[0][i], eye[phaseCenter][j] */
        *(bufferPtr + 0 * phaseMaxCount + i) = *(eyeRawData + phaseCenter * voltageMaxCount + j);
        i++;
    }

    /*
    * Record differences in vector values from a given 0-point
    * Store data in buffer[1]
    * buffer[0] = [vertical]            buffer[1] = [vertical diff]
    */
    for (i = 0; i < vectorCount; i++)
    {
        if (i == adjustedVoltageCenter)         /* Center is 0 */
        {
            /* buffer[1][i] */
            *(bufferPtr + 1 * phaseMaxCount + i) = 0;
        }
        else if (i < adjustedVoltageCenter)     /* Subtract towards 0 */
        {
            /* buffer[1][i], buffer[0][i], buffer[0][i + 1] */
            *(bufferPtr + 1 * phaseMaxCount + i) = *(bufferPtr + 0 * phaseMaxCount + i) - *(bufferPtr + 0 * phaseMaxCount + (i + 1));
        }
        else                                    /* Subtract towards 0 */
        {
            /* buffer[1][i], buffer[0][i], buffer[0][i - 1] */
            *(bufferPtr + 1 * phaseMaxCount + i) = *(bufferPtr + 0 * phaseMaxCount + i) - *(bufferPtr + 0 * phaseMaxCount + (i - 1));
        }
    }

    /*
    * PDF (Probability Distribution Function)
    * Store data in buffer[0]
    * buffer[0] = [vertical diff pdf]   buffer[1] = [vertical diff]
    */
    x_double = 0;   /* Total vertical differences */
    for (i = 0; i < vectorCount; i++)
    {
        /* buffer[1][i] */
        x_double += *(bufferPtr + 1 * phaseMaxCount + i);
    }
    if (0 == x_double)
        return CLI_SUCCESS;    /* Invalid data */
    for (i = 0; i < vectorCount; i++)
    {
        /* buffer[0][i], buffer[1][i] */
        *(bufferPtr + 0 * phaseMaxCount + i) = *(bufferPtr + 1 * phaseMaxCount + i) / x_double;
    }

    /*
    * CDF (Cumulative Distribution Function)
    * Store data in buffer[1]
    * buffer[0] = [vertical diff pdf]   buffer[1] = [vertical diff cdf]
    */
    /* buffer[1][0] */
    *(bufferPtr + 1 * phaseMaxCount + 0) = 0;
    for (i = 1; i < vectorCount; i++)
    {
        /* buffer[1][i], buffer[1][i - 1], buffer[0][i] */
        *(bufferPtr + 1 * phaseMaxCount + i) = *(bufferPtr + 1 * phaseMaxCount + (i - 1)) + *(bufferPtr + 0 * phaseMaxCount + i);
    }

    /*
    * Finds ranges of equal probability in the given cdf and trims the segments to remove leading/trailing zeros
    * Ranges for the two segments are in (segment0Min, segment0Max) and (segment1Min, segment1Max)
    * buffer[0] = [vertical diff pdf]   buffer[1] = [vertical diff cdf]
    */
    /* buffer[1][vectorCount - 1], buffer[1][0] */
    x_double = *(bufferPtr + 1 * phaseMaxCount + (vectorCount - 1)) - *(bufferPtr + 1 * phaseMaxCount + 0); /* Total probability */
    /* buffer[1][0] */
    y_double = *(bufferPtr + 1 * phaseMaxCount + 0) + x_double / 4; /* Target find probability */
    findCount = 0;
    segment0Max = 0;
    for (i = 1; i < vectorCount; i++)
    {
        /* buffer[1][i] */
        if ((*(bufferPtr + 1 * phaseMaxCount + i)) > y_double)
        {
            /* Store closest index to value */
            /* buffer[1][i], buffer[1][i - 1] */
            findHist[findCount % 2] = i - (((y_double - *(bufferPtr + 1 * phaseMaxCount + i)) + (y_double - *(bufferPtr + 1 * phaseMaxCount + (i - 1)))) <= 0);

            y_double += x_double / 2;   /* Target find probability readjusted */
            findCount++;

            if (findCount > 1)
            {
                /* Average history to get bound estimate */
                segment0Max = (uint32)(sal_round(((findHist[0] + findHist[1]) / 2)*100, 1) / 100);
                segment1Min = segment0Max;
                break;
            }
        }
    }
    segment0Min = 0;
    segment1Max = vectorCount - 1;

    /*
    * Finds the mean index based on the weights at each index
    * Mean index for the two segements are in mean0 and mean1
    * buffer[0] = [vertical diff pdf]   buffer[1] = [vertical diff cdf]
    */
    x_double = 0;
    y_double = 0;
    for (i = segment0Min; i <= segment0Max; i++)    /* Segment0 */
    {
        /* buffer[0][i] */
        x_double += *(bufferPtr + 0 * phaseMaxCount + i) * i;   /* Total by weight */
        /* buffer[0][i] */
        y_double += *(bufferPtr + 0 * phaseMaxCount + i);       /* Total */
    }
    if (0 == y_double)
        return CLI_SUCCESS;    /* Invalid data */
    mean0 = x_double / y_double;
    amplitudeStats->upperMean = adjustedVoltageCenter - mean0;
    x_double = 0;
    y_double = 0;
    for (i = segment1Min; i <= segment1Max; i++)    /* Segment1 */
    {
        /* buffer[0][i] */
        x_double += *(bufferPtr + 0 * phaseMaxCount + i) * i;   /* Total by weight */
        /* buffer[0][i] */
        y_double += *(bufferPtr + 0 * phaseMaxCount + i);       /* Total */
    }
    if (0 == y_double)
        return CLI_SUCCESS;    /* Invalid data */
    mean1 = x_double / y_double;
    amplitudeStats->lowerMean = mean1 - adjustedVoltageCenter;

    /*
    * Search outward from the passing region, looking for the first negative probability to trim noise and real variance outliers
    * Center is closest to segment0Max and segment1Min, step direction is -1 and +1 respectively to step towards edge
    * buffer[0] = [vertical diff pdf]   buffer[1] = [vertical diff cdf]
    */
    for (i = (uint32)(sal_round(mean0*100, 1) / 100); i < vectorCount; i--) /* Segment0, Sweep from mean to edge */
    {
        /* buffer[0][i] */
        if (*(bufferPtr + 0 * phaseMaxCount + i) < 0)
        {
            segment0Min = i + 1;
            break;
        }

        if (0 == i)
            break;
    }
    for (i = (uint32)(sal_round(mean1*100, 1) / 100); i < vectorCount; i++) /* Segment1, Sweep from mean to edge */
    {
        /* buffer[0][i] */
        if (*(bufferPtr + 0 * phaseMaxCount + i) < 0)
        {
            segment1Max = i + 1;
            break;
        }
    }

    /*
    * Find index stdev based on weights at each index
    * Standard deviation index for the two segements are in stdev0 and stdev1
    * buffer[0] = [vertical diff pdf]   buffer[1] = [vertical diff cdf]
    */
    x_double = 0;
    y_double = 0;
    for (i = segment0Min; i <= segment0Max; i++)    /* Segment0 */
    {
        /* buffer[0][i] */
        x_double += *(bufferPtr + 0 * phaseMaxCount + i) * sal_pow((i - mean0), 2); /* Weighted sum of deviation squared */
        /* buffer[0][i] */
        y_double += *(bufferPtr + 0 * phaseMaxCount + i);   /* Total */
    }
    if (0 == y_double)
        return CLI_SUCCESS;    /* Invalid data */
    stdev0 = sal_sqrt(x_double / y_double);
    amplitudeStats->upperStdDev = stdev0;
    x_double = 0;
    y_double = 0;
    for (i = segment1Min; i <= segment1Max; i++)    /* Segment1 */
    {
        /* buffer[0][i] */
        x_double += *(bufferPtr + 0 * phaseMaxCount + i) * sal_pow((i - mean1), 2); /* Weighted sum of deviation squared */
        /* buffer[0][i] */
        y_double += *(bufferPtr + 0 * phaseMaxCount + i);   /* Total */
    }
    if (0 == y_double)
        return CLI_SUCCESS;    /* Invalid data */
    stdev1 = sal_sqrt(x_double / y_double);
    amplitudeStats->lowerStdDev = stdev1;

    /*
    * Calculate Q factor and SNR
    * buffer[0] = [vertical diff pdf]   buffer[1] = [vertical diff cdf]
    */
    x_double = sal_pow((mean0 - adjustedVoltageCenter), 2) + sal_pow((mean1 - adjustedVoltageCenter), 2);   /* SPWR */
    y_double = sal_pow(stdev0, 2) + sal_pow(stdev1, 2); /* NPWR */
    if (0 == y_double)
        return CLI_SUCCESS;    /* Invalid data */

    amplitudeStats->Q = sal_sqrt(x_double / y_double);
    log = sal_log10(x_double / y_double);
    amplitudeStats->SNR = 10 * log;     /* dB */

    return CLI_SUCCESS;
}
#endif

void
_ctc_at_dkit_eom_get_meas_para(uint32 level_prc, uint32* p_min_sample, uint32* p_ber_thrd)
{
    uint32 min_sample, ber_thrd;
    switch(level_prc)
    {
        case DKIT_EOM_PRECISION_L1: /*ber < 10^-4, sample count >= 10^5, error tolerance < 10*/
            min_sample = 100000;
            ber_thrd = 10;
            break;
        case DKIT_EOM_PRECISION_L3: /*ber < 10^-5, sample count >= 10^6, error tolerance < 10*/
            min_sample = 1000000;
            ber_thrd = 10;
            break;
        case DKIT_EOM_PRECISION_L4: /*ber < 10^-5, sample count >= 10^9, error tolerance < 10000*/
            min_sample = 1000000000;
            ber_thrd = 10000;
            break;
        case DKIT_EOM_PRECISION_L5: /*ber < 10^-7, sample count >= 10^9, error tolerance < 100*/
            min_sample = 1000000000;
            ber_thrd = 100;
            break;
        case DKIT_EOM_PRECISION_L2:
        default:                    /*ber < 10^-5, sample count >= 10^5, error tolerance < 1*/
            min_sample = 100000;
            ber_thrd = 1;
            break;
    }
    if(p_min_sample) *p_min_sample = min_sample;
    if(p_ber_thrd)   *p_ber_thrd = ber_thrd;
}

void _ctc_at_dkit_get_snr(ctc_at_dkit_serdes_dev_t* p_dev, uint32* snr_db, uint32* snr_reg)
{

    uint32 rxEqMonClkEnData, rxPam2EnData;
    uint32 mseValData;
#ifdef CTC_MATH_FLOATING
    uint64 mseValDataL;
    int64 log = 0;
#endif

#if 0
    uint8  modulation;
    uint32 min_samples    = 0;
    uint32 ber_thrd       = 0; 
    uint8  eom_stats_mode = 0;
    uint8  tmb            = 0;
    uint8  tmb_start      = 0;
    uint8  tmb_end        = 0;
    uint32 i, j;
    _dkit_at_serdes_56g_eye_buffer_t* buffer_ptr = NULL;
    _dkit_at_serdes_56g_eom_data_t* eom_data = NULL;
    _dkit_at_eom_stats_eye_amp_t amp = {0};
    double snr[DKIT_EYE_TMB_BUTT] = {0};
#endif

    if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        *snr_db = 0;
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EQ_MON_CLK_EN), CTC_AT_DKIT_SERDES_REG_LANE, &rxEqMonClkEnData);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EQ_MON_CLK_EN), CTC_AT_DKIT_SERDES_REG_LANE, 1);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_MSE_START), CTC_AT_DKIT_SERDES_REG_LANE, 0);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_MSE_EN), CTC_AT_DKIT_SERDES_REG_LANE, 1);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_MSE_ADAPT_EN), CTC_AT_DKIT_SERDES_REG_LANE, 0);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_MSE_MODE), CTC_AT_DKIT_SERDES_REG_LANE, 0);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_MSE_CONT_MODE), CTC_AT_DKIT_SERDES_REG_LANE, 0);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_MSE_RD_REQ), CTC_AT_DKIT_SERDES_REG_LANE, 0);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_MSE_START), CTC_AT_DKIT_SERDES_REG_LANE, 1);
        if(CLI_SUCCESS != _ctc_at_dkit_serdes_poll_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_MSE_DONE), CTC_AT_DKIT_SERDES_REG_LANE, 1)) return;
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_MSE_RD_REQ), CTC_AT_DKIT_SERDES_REG_LANE, 1);
        if(CLI_SUCCESS != _ctc_at_dkit_serdes_poll_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_MSE_RD_ACK), CTC_AT_DKIT_SERDES_REG_LANE, 1)) return;
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_MSE_VAL), CTC_AT_DKIT_SERDES_REG_LANE, &mseValData);
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_PAM2_EN), CTC_AT_DKIT_SERDES_REG_LANE, &rxPam2EnData);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_MSE_RD_REQ), CTC_AT_DKIT_SERDES_REG_LANE, 0);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_MSE_START), CTC_AT_DKIT_SERDES_REG_LANE, 0);
    
        if(0 == rxEqMonClkEnData)
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EQ_MON_CLK_EN), CTC_AT_DKIT_SERDES_REG_LANE, 0);
        }
       
        if(0 == mseValData)
        {
            return;
        }
        
        if(1 == rxPam2EnData)
        {
#ifdef CTC_MATH_FLOATING
            mseValDataL = (uint64)mseValData*1000000; /*enlarge to 10e6 to prevent intlog10 inupt 0*/
            log = ((sal_log10(mseValDataL / (9 * 65536)) * 1000) / 16777216) - (6 * 1000);
            *snr_db = (uint32)(-10 * log);
#else
            *snr_db = 0;
            CTC_DKIT_PRINT("snr = (uint32)(1000 * (-10.0 * log10((double)%u / ((double)9 * 65536))))\n", mseValData);
#endif
        }
        else 
        {
#ifdef CTC_MATH_FLOATING
            mseValDataL = (uint64)mseValData*1000000; /*enlarge to 10e6 to prevent intlog10 inupt 0*/
            log = ((sal_log10(mseValDataL / 65536) * 1000) / 16777216) - (6 * 1000);
            *snr_db = (uint32)(1000 * 7 + (-10 * log));
#else
            *snr_db = 0;
            CTC_DKIT_PRINT("snr = (uint32)(1000 * (7 + (-10.0 * log10((double)%u / 65536))))\n", mseValData);
#endif
        }
        *snr_reg = mseValData;
    }
    else
    {
#if 0
        _ctc_at_dkit_eom_get_meas_para(DKIT_EOM_PRECISION_L3, &min_samples, &ber_thrd);

        buffer_ptr = (_dkit_at_serdes_56g_eye_buffer_t*)mem_malloc(MEM_SYSTEM_MODULE, sizeof(_dkit_at_serdes_56g_eye_buffer_t));
        eom_data = (_dkit_at_serdes_56g_eom_data_t*)mem_malloc(MEM_SYSTEM_MODULE, sizeof(_dkit_at_serdes_56g_eom_data_t));
        modulation = _ctc_at_dkit_get_serdes_modulation_mode(p_dev);
        
        if(modulation == CTC_DKIT_AT_SERDES_NRZ_MODE)
        {
            tmb_start = DKIT_EYE_MID;
            tmb_end   = DKIT_EYE_MID;  
        }
        else if(modulation == CTC_DKIT_AT_SERDES_PAM4_MODE)
        {
            tmb_start = DKIT_EYE_BOT;
            tmb_end   = DKIT_EYE_TOP;  
        }
        
        for(tmb = tmb_start; tmb <= tmb_end; tmb++)
        {
            for(i = 0; i < DKIT_AT56G_EYE_MAX_PHASE_LEVEL; i++)
            {
                for(j = 0; j < (DKIT_AT56G_EYE_MAX_VOLT_STEPS * 2) - 1; j++)
                {
                    eom_data->eyeRawData[i][j] = min_samples;
                }
            }
            if(CLI_SUCCESS != _ctc_at_dkit_eom_get_eye_data(p_dev, tmb, min_samples, ber_thrd, eom_stats_mode, (void*)eom_data))
            {
                return;
            }
            _ctc_at_dkit_eom_stats_get_amplitute_stat(p_dev, buffer_ptr->bufferData[0], eom_data->relativeCenter, 
                DKIT_AT56G_EYE_MAX_PHASE_LEVEL, eom_data->upperEdge, eom_data->lowerEdge, 
                DKIT_AT56G_EYE_MAX_VOLT_STEPS-1, (2*DKIT_AT56G_EYE_MAX_VOLT_STEPS-1), 
                eom_data->eyeRawData[0], &amp);
            snr[tmb] = amp.SNR;
        }
        if(modulation == CTC_DKIT_AT_SERDES_NRZ_MODE)
        {
            *snr_db = (uint32)(1000 * snr[DKIT_EYE_MID]);
        }
        else if(modulation == CTC_DKIT_AT_SERDES_PAM4_MODE)
        {
            *snr_db = (uint32)(1000 * ((snr[DKIT_EYE_BOT] + snr[DKIT_EYE_MID] + snr[DKIT_EYE_TOP]) / 3));
        }
        CTC_DKIT_PRINT("B %lf, M %lf, T %lf\n", snr[DKIT_EYE_BOT], snr[DKIT_EYE_MID], snr[DKIT_EYE_TOP]);
        
        mem_free(eom_data);
        mem_free(buffer_ptr);
#else
        /* CTC_DKIT_PRINT("Feature not support!\n"); */
#endif
        *snr_db = 0;
    }
}

void _ctc_at_dkit_set_dfe_freeze_updates(ctc_at_dkit_serdes_dev_t* p_dev, uint32 freeze)
{
 
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_DFE_UP_DIS), CTC_AT_DKIT_SERDES_REG_LANE, freeze);
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        /* current not support */
    }

}


void _ctc_at_dkit_get_dfe_freeze_updates(ctc_at_dkit_serdes_dev_t* p_dev, uint8* freeze)
{
    uint32 value = 0;

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_DFE_UP_DIS), CTC_AT_DKIT_SERDES_REG_LANE, &value);
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        value = DKIT_AT_USELESS_ID32;
    }

    *freeze = (uint8)value;

}

void _ctc_at_dkit_112g_get_ffe_tap(ctc_at_dkit_serdes_dev_t* p_dev, uint8 tmb, uint8 ffe_tap, int32* tap_value)
{
    uint32 gainData;
    *tap_value = 0;
    switch(ffe_tap)
    {
        case DKIT_AT112G_FFE_PRE_6:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PRE6), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PRE_5:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PRE5), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PRE_4:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PRE4), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PRE_3:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PRE3), tap_value);
            }
            else if (DKIT_AT112G_CLOCK_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DTL_PRE3), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PRE_2:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PRE2), tap_value);
            }
            else if (DKIT_AT112G_CLOCK_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DTL_PRE2), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PRE_1:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PRE1), tap_value);
            }
            else if (DKIT_AT112G_CLOCK_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DTL_PRE1), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_1:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST1), tap_value);
            }
            else if (DKIT_AT112G_CLOCK_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DTL_PST1), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_2:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST2), tap_value);
            }
            else if (DKIT_AT112G_CLOCK_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DTL_PST2), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_3:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST3), tap_value);
            }
            else if (DKIT_AT112G_CLOCK_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DTL_PST3), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_4:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST4), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_5:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST5), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_6:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST6), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_7:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST7), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_8:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST8), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_9:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST9), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_10:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST10), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_11:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST11), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_12:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST12), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_13:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST13), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_14:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST14), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_15:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST15), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_PST_16:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_PST16), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_GAIN:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_GAIN), CTC_AT_DKIT_SERDES_REG_LANE, &gainData);
                *tap_value = gainData;
            }
            else if (DKIT_AT112G_CLOCK_PATH == tmb)
            {
                _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DTL_GAIN), CTC_AT_DKIT_SERDES_REG_LANE, &gainData);
                *tap_value = gainData;
            }
        }
        break;
        case DKIT_AT112G_FFE_BLW:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_BLW), tap_value);
            }
            else if (DKIT_AT112G_CLOCK_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DTL_BLW), tap_value);
            }
        }
        break;
        case DKIT_AT112G_FFE_DFE:
        {
            if (DKIT_AT112G_DATA_PATH == tmb)
            {
                _ctc_at_dkit_convert_to_codes(p_dev, DKIT_REG_STR(F_DKIT_AT112G_DP_DFE), tap_value);
            }
        }
        break;
        default:
        break;
    }
    
}

void _ctc_at_dkit_56g_get_dfe_tap(ctc_at_dkit_serdes_dev_t* p_dev, uint8 tmb, uint8 dfe_tap, int32* tap_value)
{
    *tap_value = 0;
    switch (dfe_tap)
    {
        case DKIT_AT56G_DFE_DC:
        {
            _ctc_at_dkit_serdes_field_t fieldList[3] = { F_DKIT_AT56G_DC_D_T_E_SM, F_DKIT_AT56G_DC_D_M_E_SM, F_DKIT_AT56G_DC_D_B_E_SM };
            _ctc_at_dkit_convert_to_millicodes(p_dev, &(fieldList[tmb]), tap_value);
        }
        break;
        case DKIT_AT56G_DFE_DC_E:
        {
            _ctc_at_dkit_convert_to_millicodes(p_dev, DKIT_REG_STR(F_DKIT_AT56G_DC_E_E_SM), tap_value);
        }
        break;
        case DKIT_AT56G_DFE_VREF:
        {
            _ctc_at_dkit_serdes_field_t fieldList[3] = { F_DKIT_AT56G_VREF_T_E_SM, F_DKIT_AT56G_VREF_M_E_SM, F_DKIT_AT56G_VREF_B_E_SM };
            _ctc_at_dkit_convert_to_millicodes(p_dev, &(fieldList[tmb]), tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F0:
        {
            _ctc_at_dkit_serdes_field_t fieldList[3] = { F_DKIT_AT56G_F0_D_T_E_SM, F_DKIT_AT56G_F0_D_M_E_SM, F_DKIT_AT56G_F0_D_B_E_SM };
            uint32 data;
    
            _ctc_at_dkit_serdes_read_reg_field(p_dev, &(fieldList[tmb]), CTC_AT_DKIT_SERDES_REG_LANE, &data);
            *tap_value = data * 1000; /* F0 tap is not signed. Unlike other DFE taps, we do not treat it like signed magnitude */
        }
        break;
        case DKIT_AT56G_DFE_F1:
        {
            _ctc_at_dkit_serdes_field_t fieldList[3] = { F_DKIT_AT56G_F1_D_T_E_SM, F_DKIT_AT56G_F1_D_M_E_SM, F_DKIT_AT56G_F1_D_B_E_SM };
    
            _ctc_at_dkit_convert_to_millicodes(p_dev, &(fieldList[tmb]), tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F1P5:
        {
            _ctc_at_dkit_convert_to_millicodes(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F1P5_E_SM), tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F2:
        {
            _ctc_at_dkit_serdes_field_t fieldList[3] = { F_DKIT_AT56G_F2_D_T_E_SM, F_DKIT_AT56G_F2_D_M_E_SM, F_DKIT_AT56G_F2_D_B_E_SM };
    
            _ctc_at_dkit_convert_to_millicodes(p_dev, &(fieldList[tmb]), tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F3:
        {
            _ctc_at_dkit_serdes_field_t fieldList[3] = { F_DKIT_AT56G_F3_T_E_SM, F_DKIT_AT56G_F3_M_E_SM, F_DKIT_AT56G_F3_B_E_SM };
    
            _ctc_at_dkit_convert_to_average_millicodes(p_dev, &fieldList[0], &fieldList[1], &fieldList[2], tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F4:
        {
            _ctc_at_dkit_serdes_field_t fieldList[3] = { F_DKIT_AT56G_F4_T_E_SM, F_DKIT_AT56G_F4_M_E_SM, F_DKIT_AT56G_F4_B_E_SM };
    
            _ctc_at_dkit_convert_to_average_millicodes(p_dev, &fieldList[0], &fieldList[1], &fieldList[2], tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F5:
        {
            _ctc_at_dkit_serdes_field_t msb_field = F_DKIT_AT56G_F5_MSB_E_SM;
            _ctc_at_dkit_serdes_field_t lsb_field = F_DKIT_AT56G_F5_LSB_E_SM;
    
            _ctc_at_dkit_convert_msblsb_to_millicodes(p_dev, &msb_field, &lsb_field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F6:
        {
            _ctc_at_dkit_serdes_field_t msb_field = F_DKIT_AT56G_F6_MSB_E_SM;
            _ctc_at_dkit_serdes_field_t lsb_field = F_DKIT_AT56G_F6_LSB_E_SM;
    
            _ctc_at_dkit_convert_msblsb_to_millicodes(p_dev, &msb_field, &lsb_field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F7:
        {
            _ctc_at_dkit_serdes_field_t msb_field = F_DKIT_AT56G_F7_MSB_E_SM;
            _ctc_at_dkit_serdes_field_t lsb_field = F_DKIT_AT56G_F7_LSB_E_SM;
    
            _ctc_at_dkit_convert_msblsb_to_millicodes(p_dev, &msb_field, &lsb_field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F8:
        {
            _ctc_at_dkit_serdes_field_t msb_field = F_DKIT_AT56G_F8_MSB_E_SM;
            _ctc_at_dkit_serdes_field_t lsb_field = F_DKIT_AT56G_F8_LSB_E_SM;
    
            _ctc_at_dkit_convert_msblsb_to_millicodes(p_dev, &msb_field, &lsb_field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F9:
        {
            _ctc_at_dkit_serdes_field_t msb_field = F_DKIT_AT56G_F9_MSB_E_SM;
            _ctc_at_dkit_serdes_field_t lsb_field = F_DKIT_AT56G_F9_LSB_E_SM;
    
            _ctc_at_dkit_convert_msblsb_to_millicodes(p_dev, &msb_field, &lsb_field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F10:
        {
            _ctc_at_dkit_serdes_field_t msb_field = F_DKIT_AT56G_F10_MSB_E_SM;
            _ctc_at_dkit_serdes_field_t lsb_field = F_DKIT_AT56G_F10_LSB_E_SM;
    
            _ctc_at_dkit_convert_msblsb_to_millicodes(p_dev, &msb_field, &lsb_field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F11:
        {
            _ctc_at_dkit_serdes_field_t field = F_DKIT_AT56G_F11_E_SM;
    
            _ctc_at_dkit_convert_to_millicodes(p_dev, &field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F12:
        {
            _ctc_at_dkit_serdes_field_t field = F_DKIT_AT56G_F12_E_SM;
    
            _ctc_at_dkit_convert_to_millicodes(p_dev, &field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F13:
        {
            _ctc_at_dkit_serdes_field_t field = F_DKIT_AT56G_F13_E_SM;
    
            _ctc_at_dkit_convert_to_millicodes(p_dev, &field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F14:
        {
            _ctc_at_dkit_serdes_field_t field = F_DKIT_AT56G_F14_E_SM;
    
            _ctc_at_dkit_convert_to_millicodes(p_dev, &field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_F15:
        {
            _ctc_at_dkit_serdes_field_t field = F_DKIT_AT56G_F15_E_SM;
    
            _ctc_at_dkit_convert_to_millicodes(p_dev, &field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_FF0:
        {
            _ctc_at_dkit_serdes_field_t field = F_DKIT_AT56G_FF0_E_SM;
    
            _ctc_at_dkit_convert_to_millicodes(p_dev, &field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_FF1:
        {
            _ctc_at_dkit_serdes_field_t field = F_DKIT_AT56G_FF1_E_SM;
    
            _ctc_at_dkit_convert_to_millicodes(p_dev, &field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_FF2:
        {
            _ctc_at_dkit_serdes_field_t field = F_DKIT_AT56G_FF2_E_SM;
    
            _ctc_at_dkit_convert_to_millicodes(p_dev, &field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_FF3:
        {
            _ctc_at_dkit_serdes_field_t field = F_DKIT_AT56G_FF3_E_SM;
    
            _ctc_at_dkit_convert_to_millicodes(p_dev, &field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_FF4:
        {
            _ctc_at_dkit_serdes_field_t field = F_DKIT_AT56G_FF4_E_SM;
    
            _ctc_at_dkit_convert_to_millicodes(p_dev, &field, tap_value);
        }
        break;
        case DKIT_AT56G_DFE_FF5:
        {
            _ctc_at_dkit_serdes_field_t field = F_DKIT_AT56G_FF5_E_SM;
    
            _ctc_at_dkit_convert_to_millicodes(p_dev, &field, tap_value);
        }
        break;
        default:
        break;
    }
    
}

void _ctc_at_dkit_get_dfe_tap(ctc_at_dkit_serdes_dev_t* p_dev, uint8 tmb, void* dfe_param)
{
    _dkit_at_serdes_112g_ffe_tap_param_t* ffe_112g = (_dkit_at_serdes_112g_ffe_tap_param_t*)dfe_param;
    _dkit_at_serdes_56g_dfe_tap_param_t* dfe_56g = (_dkit_at_serdes_56g_dfe_tap_param_t*)dfe_param;
    
    if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PRE_6 , &ffe_112g->dkit_ffe_tap_pre_6 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PRE_5 , &ffe_112g->dkit_ffe_tap_pre_5 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PRE_4 , &ffe_112g->dkit_ffe_tap_pre_4 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PRE_3 , &ffe_112g->dkit_ffe_tap_pre_3 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PRE_2 , &ffe_112g->dkit_ffe_tap_pre_2 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PRE_1 , &ffe_112g->dkit_ffe_tap_pre_1 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_1 , &ffe_112g->dkit_ffe_tap_pst_1 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_2 , &ffe_112g->dkit_ffe_tap_pst_2 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_3 , &ffe_112g->dkit_ffe_tap_pst_3 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_4 , &ffe_112g->dkit_ffe_tap_pst_4 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_5 , &ffe_112g->dkit_ffe_tap_pst_5 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_6 , &ffe_112g->dkit_ffe_tap_pst_6 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_7 , &ffe_112g->dkit_ffe_tap_pst_7 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_8 , &ffe_112g->dkit_ffe_tap_pst_8 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_9 , &ffe_112g->dkit_ffe_tap_pst_9 );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_10, &ffe_112g->dkit_ffe_tap_pst_10);
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_11, &ffe_112g->dkit_ffe_tap_pst_11);
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_12, &ffe_112g->dkit_ffe_tap_pst_12);
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_13, &ffe_112g->dkit_ffe_tap_pst_13);
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_14, &ffe_112g->dkit_ffe_tap_pst_14);
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_15, &ffe_112g->dkit_ffe_tap_pst_15);
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_PST_16, &ffe_112g->dkit_ffe_tap_pst_16);
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_GAIN  , &ffe_112g->dkit_ffe_tap_gain  );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_BLW   , &ffe_112g->dkit_ffe_tap_blw   );
        _ctc_at_dkit_112g_get_ffe_tap(p_dev, tmb, DKIT_AT112G_FFE_DFE   , &ffe_112g->dkit_ffe_tap_dfe   );
    }
    else if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_DC   , &dfe_56g->dkit_dfe_tap_dc  );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_DC_E , &dfe_56g->dkit_dfe_tap_dc_e);
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_VREF , &dfe_56g->dkit_dfe_tap_vref);
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F0   , &dfe_56g->dkit_dfe_tap_f0  );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F1   , &dfe_56g->dkit_dfe_tap_f1  );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F1P5 , &dfe_56g->dkit_dfe_tap_f1p5);
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F2   , &dfe_56g->dkit_dfe_tap_f2  );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F3   , &dfe_56g->dkit_dfe_tap_f3  );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F4   , &dfe_56g->dkit_dfe_tap_f4  );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F5   , &dfe_56g->dkit_dfe_tap_f5  );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F6   , &dfe_56g->dkit_dfe_tap_f6  );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F7   , &dfe_56g->dkit_dfe_tap_f7  );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F8   , &dfe_56g->dkit_dfe_tap_f8  );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F9   , &dfe_56g->dkit_dfe_tap_f9  );        
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F10  , &dfe_56g->dkit_dfe_tap_f10 );    
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F11  , &dfe_56g->dkit_dfe_tap_f11 );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F12  , &dfe_56g->dkit_dfe_tap_f12 );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F13  , &dfe_56g->dkit_dfe_tap_f13 );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F14  , &dfe_56g->dkit_dfe_tap_f14 );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_F15  , &dfe_56g->dkit_dfe_tap_f15 );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_FF0  , &dfe_56g->dkit_dfe_tap_ff0 );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_FF1  , &dfe_56g->dkit_dfe_tap_ff1 );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_FF2  , &dfe_56g->dkit_dfe_tap_ff2 );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_FF3  , &dfe_56g->dkit_dfe_tap_ff3 );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_FF4  , &dfe_56g->dkit_dfe_tap_ff4 );
        _ctc_at_dkit_56g_get_dfe_tap(p_dev, tmb, DKIT_AT56G_DFE_FF5  , &dfe_56g->dkit_dfe_tap_ff5 );
    }

}

void _ctc_at_dkit_set_power_ivref(ctc_at_dkit_serdes_dev_t* p_dev, uint16 enable)
{
    if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_PU_IVREF, enable);
    }
    else if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_PU_IVREF, enable);
    }
}

void _ctc_at_dkit_rx_init(ctc_at_dkit_serdes_dev_t* p_dev)
{
    uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    
    if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_INIT0, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_RX_INITDONE0, 1);   
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_INIT0, 0);
                break;    
            case 1:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_INIT1, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_RX_INITDONE1, 1);   
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_INIT1, 0);
                break;    
            case 2:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_INIT2, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_RX_INITDONE2, 1);   
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_INIT2, 0);
                break;    
            case 3:
            default:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_INIT3, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_RX_INITDONE3, 1);   
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_INIT3, 0);
                break;    
        }
    }
    else if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_INIT0, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_RX_INITDON0, 1);   
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_INIT0, 0);
                break;    
            case 1:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_INIT1, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_RX_INITDON1, 1);   
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_INIT1, 0);
                break;    
            case 2:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_INIT2, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_RX_INITDON2, 1);   
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_INIT2, 0);
                break;    
            case 3:
            default:
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_INIT3, 1);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_RX_INITDON3, 1);   
                _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_INIT3, 0);
                break;    
        }
   }
    
}

void _ctc_at_dkit_set_global_reset(ctc_at_dkit_serdes_dev_t* p_dev, uint16 reset)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RESET, reset);
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RESET, reset);
    }
}

void _ctc_at_dkit_set_pram_reset(ctc_at_dkit_serdes_dev_t* p_dev, uint16 reset)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_PRAM_RESET, reset);
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_PRAM_RESET, reset);
    }
}

void _ctc_at_dkit_wait_txrx_rstdone(ctc_at_dkit_serdes_dev_t* p_dev)
{
    uint16 exp_value = 1;
    uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_TX_RST_ACK0, exp_value);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_RX_RST_ACK0, exp_value);
                break;
            case 1:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_TX_RST_ACK1, exp_value);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_RX_RST_ACK1, exp_value);
                break;
            case 2:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_TX_RST_ACK2, exp_value);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_RX_RST_ACK2, exp_value);
                break;
            case 3:
            default:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_TX_RST_ACK3, exp_value);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT56G_PIN_RX_RST_ACK3, exp_value);
                break;
        }
    }
    else
    {
        switch(lane)
        {
            case 0:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_TX_RST_ACK0, exp_value);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_RX_RST_ACK0, exp_value);
                break;
            case 1:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_TX_RST_ACK1, exp_value);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_RX_RST_ACK1, exp_value);
                break;
            case 2:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_TX_RST_ACK2, exp_value);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_RX_RST_ACK2, exp_value);
                break;
            case 3:
            default:
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_TX_RST_ACK3, exp_value);
                _ctc_at_dkit_serdes_poll_pin(p_dev, DKIT_AT112G_PIN_RX_RST_ACK3, exp_value);
                break;
        }
    }
}



void _ctc_at_dkit_set_txrx_reset(ctc_at_dkit_serdes_dev_t* p_dev, uint16 reset)
{
    uint8 lane;
    uint8 pin_num = 2;
    uint16 pin[2] = {};
    uint32 value[2] = {};
    lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);

    value[0] = reset;
    value[1] = reset;
    
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                pin[0] = DKIT_AT56G_PIN_RX_RST0;
                pin[1] = DKIT_AT56G_PIN_TX_RST0;
                _ctc_at_dkit_serdes_set_pin_array(p_dev, pin_num, pin, value);
                break;
            case 1:
                pin[0] = DKIT_AT56G_PIN_RX_RST1;
                pin[1] = DKIT_AT56G_PIN_TX_RST1;
                _ctc_at_dkit_serdes_set_pin_array(p_dev, pin_num, pin, value);
                break;
            case 2:
                pin[0] = DKIT_AT56G_PIN_RX_RST2;
                pin[1] = DKIT_AT56G_PIN_TX_RST2;
                _ctc_at_dkit_serdes_set_pin_array(p_dev, pin_num, pin, value);
                break;
            case 3:
            default:
                pin[0] = DKIT_AT56G_PIN_RX_RST3;
                pin[1] = DKIT_AT56G_PIN_TX_RST3;
                _ctc_at_dkit_serdes_set_pin_array(p_dev, pin_num, pin, value);
                break;
        }
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                pin[0] = DKIT_AT112G_PIN_RX_RST0;
                pin[1] = DKIT_AT112G_PIN_TX_RST0;
                _ctc_at_dkit_serdes_set_pin_array(p_dev, pin_num, pin, value);
                break;
            case 1:
                pin[0] = DKIT_AT112G_PIN_RX_RST1;
                pin[1] = DKIT_AT112G_PIN_TX_RST1;
                _ctc_at_dkit_serdes_set_pin_array(p_dev, pin_num, pin, value);
                break;
            case 2:
                pin[0] = DKIT_AT112G_PIN_RX_RST2;
                pin[1] = DKIT_AT112G_PIN_TX_RST2;
                _ctc_at_dkit_serdes_set_pin_array(p_dev, pin_num, pin, value);
                break;
            case 3:
            default:
                pin[0] = DKIT_AT112G_PIN_RX_RST3;
                pin[1] = DKIT_AT112G_PIN_TX_RST3;
                _ctc_at_dkit_serdes_set_pin_array(p_dev, pin_num, pin, value);
                break;
        }
    }
}

void _ctc_at_dkit_serdes_reset(ctc_at_dkit_serdes_dev_t* p_dev, uint8 type, uint16 reset)
{
    switch(type)
    {
        case DKIT_AT_TXRX_RESET:
            if(reset)
            {
                _ctc_at_dkit_set_txrx_reset(p_dev, reset);  
            }
            else
            {
                _ctc_at_dkit_wait_txrx_rstdone(p_dev);
                _ctc_at_dkit_set_txrx_reset(p_dev, reset);  
            }
            break;
        case DKIT_AT_GLOBAL_RESET:
            _ctc_at_dkit_set_global_reset(p_dev, reset);
            break;
        case DKIT_AT_PRAM_RESET:
            _ctc_at_dkit_set_pram_reset(p_dev, reset);
            break;
        case DKIT_AT_POWER_IVREF:
            _ctc_at_dkit_set_power_ivref(p_dev, !reset);
            break;
        default:
            break;
    }

}

void _ctc_at_dkit_set_txrx_rate(ctc_at_dkit_serdes_dev_t* p_dev, uint16 tx_speed, uint16 rx_speed)
{
    uint8 lane;
    
    lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);

    if(CTC_AT_DKIT_SERDES_112G== p_dev->type)
    {
        switch (lane)
       {
        case 0:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_TX0, tx_speed);
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_RX0, rx_speed);
            break;
        case 1:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_TX1, tx_speed);
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_RX1, rx_speed);
            break;
        case 2:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_TX2, tx_speed);
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_RX2, rx_speed);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_TX3, tx_speed);
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_PHY_GEN_RX3, rx_speed);
            break;
       }    
    }
    else if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch (lane)
       {
        case 0:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_TX0, tx_speed);
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_RX0, rx_speed);
            break;
        case 1:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_TX1, tx_speed);
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_RX1, rx_speed);
            break;
        case 2:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_TX2, tx_speed);
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_RX2, rx_speed);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_TX3, tx_speed);
            _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_PHY_GEN_RX3, rx_speed);
            break;
       }
    }
}

void 
_ctc_at_dkit_set_training_timeout(ctc_at_dkit_serdes_dev_t* p_dev, uint8 type, uint8 enable, uint16 timeout)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        if(DKIT_AT_TRAINING_TRX == type)
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_TIMER_EN), CTC_AT_DKIT_SERDES_REG_LANE, (uint32)enable);    
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TRX_TIMER), CTC_AT_DKIT_SERDES_REG_LANE, (uint32)timeout);    
        }
        else if(DKIT_AT_TRAINING_RX == type)
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_TIMER_EN), CTC_AT_DKIT_SERDES_REG_LANE, (uint32)enable);    
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_TIMER), CTC_AT_DKIT_SERDES_REG_LANE, (uint32)timeout);    
        }
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        if(DKIT_AT_TRAINING_TRX == type)
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TRX_TIMEOUT_EN), CTC_AT_DKIT_SERDES_REG_LANE, (uint32)enable);    
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TRX_TIMER), CTC_AT_DKIT_SERDES_REG_LANE, (uint32)timeout);    
        }
        else if(DKIT_AT_TRAINING_RX == type)
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TRX_TIMEOUT_EN), CTC_AT_DKIT_SERDES_REG_LANE, (uint32)enable);    
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_TIMER), CTC_AT_DKIT_SERDES_REG_LANE, (uint32)timeout);    
        }
    }
}

void 
_ctc_at_dkit_get_training_timeout(ctc_at_dkit_serdes_dev_t* p_dev, uint8 type, uint8* enable, uint16* timeout)
{
    uint32 value = 0;
    uint32 value1 = 0;

    
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        if(DKIT_AT_TRAINING_TRX == type)
        {
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_TIMER_EN), CTC_AT_DKIT_SERDES_REG_LANE, &value);    
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TRX_TIMER), CTC_AT_DKIT_SERDES_REG_LANE, &value1);    
        }
        else if(DKIT_AT_TRAINING_RX == type)
        {
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_TIMER_EN), CTC_AT_DKIT_SERDES_REG_LANE, &value);    
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_TIMER), CTC_AT_DKIT_SERDES_REG_LANE, &value1);    
        }
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        if(DKIT_AT_TRAINING_TRX == type)
        {
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TRX_TIMEOUT_EN), CTC_AT_DKIT_SERDES_REG_LANE, &value);    
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TRX_TIMER), CTC_AT_DKIT_SERDES_REG_LANE, &value1);    
        }
        else if(DKIT_AT_TRAINING_RX == type)
        {
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TRX_TIMEOUT_EN), CTC_AT_DKIT_SERDES_REG_LANE, &value);    
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_TIMER), CTC_AT_DKIT_SERDES_REG_LANE, &value1);    
        }
    }

    *enable = (uint8)value;
    *timeout = (uint16)value1;
}

void _ctc_at_dkit_get_txrx_polarity(ctc_at_dkit_serdes_dev_t* p_dev, uint32* tx_polarity, uint32* rx_polarity)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TXD_INV), CTC_AT_DKIT_SERDES_REG_LANE, tx_polarity);    
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RXD_INV), CTC_AT_DKIT_SERDES_REG_LANE, rx_polarity);    
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TXD_INV), CTC_AT_DKIT_SERDES_REG_LANE, tx_polarity);    
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RXD_INV), CTC_AT_DKIT_SERDES_REG_LANE, rx_polarity);    
    }
    
}

void _ctc_at_dkit_get_comparator_stats(ctc_at_dkit_serdes_dev_t* p_dev, _dkit_at_serdes_pattern_stats_t* p_stats)
{
    /*p_stats->totalErrorBits = sal_rand() % 10000;
    p_stats->totalBits = (sal_rand() % 500000 ) * p_stats->totalErrorBits;
    printf("_ctc_at_dkit_get_comparator_stats: serdes %u, totcnt %lu, errcnt %lu\n", p_dev->serdes_id, p_stats->totalBits, p_stats->totalErrorBits);
    return;*/
    uint64 cnt = 0, errcnt = 0;
    uint32 data = 0, pass = 0, lock = 0;
    uint16 txwidth = 0,rxwidth = 0;
    uint16 width = 0;
    
    _ctc_at_dkit_get_data_width(p_dev, &txwidth, &rxwidth);
    
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch (rxwidth)
        {
            case DKIT_AT56G_DATABUS_32BIT:
                width = 32;
                break;
            case DKIT_AT56G_DATABUS_40BIT:
                width = 40;
                break;
            case DKIT_AT56G_DATABUS_64BIT:
                width = 64;
                break;
            default:
                width = 1;
                break;
        }

        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_LOCK), CTC_AT_DKIT_SERDES_REG_LANE, &lock);
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_PASS), CTC_AT_DKIT_SERDES_REG_LANE, &pass);
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_CNT_3100), CTC_AT_DKIT_SERDES_REG_LANE, &data);
        cnt = data;
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_CNT_4732), CTC_AT_DKIT_SERDES_REG_LANE, &data);
        cnt += (uint64)data << 32;
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_ERR_3100), CTC_AT_DKIT_SERDES_REG_LANE, &data);
        errcnt = data;
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_ERR_4732), CTC_AT_DKIT_SERDES_REG_LANE, &data);
        errcnt += (uint64)data << 32;
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        switch (rxwidth)
        {
            case DKIT_AT112G_DATABUS_32BIT:
                width = 32;
                break;
            case DKIT_AT112G_DATABUS_40BIT:
                width = 40;
                break;
            case DKIT_AT112G_DATABUS_64BIT:
                width = 64;
                break;
            case DKIT_AT112G_DATABUS_80BIT:
                width = 80;
                break;
            case DKIT_AT112G_DATABUS_128BIT:
                width = 128;
                break;
            case DKIT_AT112G_DATABUS_160BIT:
                width = 160;
                break;
            default:
                width = 1;
                break;
        }

        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_LOCK), CTC_AT_DKIT_SERDES_REG_LANE, &lock);
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_PASS), CTC_AT_DKIT_SERDES_REG_LANE, &pass);
        
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_CNT_31_0), CTC_AT_DKIT_SERDES_REG_LANE, &data);
        cnt = data;
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_CNT_47_32), CTC_AT_DKIT_SERDES_REG_LANE, &data);
        cnt += (uint64)data << 32;
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_ERR_31_0), CTC_AT_DKIT_SERDES_REG_LANE, &data);
        errcnt = data;
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_ERR_47_32), CTC_AT_DKIT_SERDES_REG_LANE, &data);
        errcnt += (uint64)data << 32;
    }

    p_stats->totalBits = cnt * width;
    p_stats->totalErrorBits = errcnt;
    p_stats->pass = pass;
    p_stats->lock = lock;
}

void _ctc_at_dkit_reset_comparator_stats(ctc_at_dkit_serdes_dev_t* p_dev)
{
    /*printf("_ctc_at_dkit_reset_comparator_stats: serdes %u\n", p_dev->serdes_id);
    return;*/
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_CNT_RST), CTC_AT_DKIT_SERDES_REG_LANE, 0);
        sal_task_sleep(1);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_CNT_RST), CTC_AT_DKIT_SERDES_REG_LANE, 1);
        sal_task_sleep(1);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_CNT_RST), CTC_AT_DKIT_SERDES_REG_LANE, 0);
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_CNT_RST), CTC_AT_DKIT_SERDES_REG_LANE, 0);
        sal_task_sleep(1);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_CNT_RST), CTC_AT_DKIT_SERDES_REG_LANE, 1);
        sal_task_sleep(1);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_CNT_RST), CTC_AT_DKIT_SERDES_REG_LANE, 0);
    }
    
}

/* prbs tx/rx pattern */
void
_ctc_at_dkit_set_prbs_pattern(ctc_at_dkit_serdes_dev_t* p_dev, uint8 dir, uint32 pattern)
{
    uint32 prbs_value = 0;
    uint32 pam2_en = 0;
    
    PRBS_PATTERN_TO_VALUE(pattern, prbs_value);
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        if(DKIT_AT_DIR_RX == dir)
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_PAT_SEL), CTC_AT_DKIT_SERDES_REG_LANE, prbs_value);
        }
        else if(DKIT_AT_DIR_TX == dir)
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_PAT_SEL), CTC_AT_DKIT_SERDES_REG_LANE, prbs_value);
        }
        /*8081 pattern set data width*/
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_PAM2_EN), CTC_AT_DKIT_SERDES_REG_LANE, &pam2_en);
        if(0 == pam2_en)
        {
            if(DKIT_PAT_JITTER_8T == prbs_value)
            {
                _ctc_at_dkit_set_data_width(p_dev, DKIT_AT56G_DATABUS_64BIT, DKIT_AT56G_DATABUS_64BIT);
            }
        }
        else
        {
            if(DKIT_PAT_JITTER_8T == prbs_value)
            {
                _ctc_at_dkit_set_data_width(p_dev, DKIT_AT56G_DATABUS_32BIT, DKIT_AT56G_DATABUS_32BIT);
            }
        }
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        if(DKIT_AT_DIR_RX == dir)
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_PATTERN_SEL), CTC_AT_DKIT_SERDES_REG_LANE, prbs_value);
        }
        else if(DKIT_AT_DIR_TX == dir)
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_PATTERN_SEL), CTC_AT_DKIT_SERDES_REG_LANE, prbs_value);
        }
        /*8081 pattern set data width*/
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_DATA_WIDTH), CTC_AT_DKIT_SERDES_REG_LANE, &pam2_en);
        if(pam2_en == DKIT_AT112G_RATE_FULL)
        {
            if(DKIT_PAT_JITTER_8T == prbs_value)
            {
                _ctc_at_dkit_set_data_width(p_dev, DKIT_AT112G_DATABUS_32BIT, DKIT_AT112G_DATABUS_32BIT);
            }
        }
        else if(pam2_en == DKIT_AT112G_RATE_HALF)
        {
            if(DKIT_PAT_JITTER_8T == prbs_value)
            {
                _ctc_at_dkit_set_data_width(p_dev, DKIT_AT112G_DATABUS_64BIT, DKIT_AT112G_DATABUS_64BIT);
            }
        }
        else if(pam2_en == DKIT_AT112G_RATE_QUARTER)
        {
            if(DKIT_PAT_JITTER_8T == prbs_value)
            {
                _ctc_at_dkit_set_data_width(p_dev, DKIT_AT112G_DATABUS_128BIT, DKIT_AT112G_DATABUS_128BIT);
            }
        }
    }
}

void
_ctc_at_dkit_get_prbs_pattern(ctc_at_dkit_serdes_dev_t* p_dev, uint8 dir, uint32* pattern)
{
    uint32 prbs_value = 0;

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        if(DKIT_AT_DIR_RX == dir)
        {
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_PAT_SEL), CTC_AT_DKIT_SERDES_REG_LANE, &prbs_value);
        }
        else if(DKIT_AT_DIR_TX == dir)
        {
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_PAT_SEL), CTC_AT_DKIT_SERDES_REG_LANE, &prbs_value);
        }
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        if(DKIT_AT_DIR_RX == dir)
        {
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_PATTERN_SEL), CTC_AT_DKIT_SERDES_REG_LANE, &prbs_value);
        }
        else if(DKIT_AT_DIR_TX == dir)
        {
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_PATTERN_SEL), CTC_AT_DKIT_SERDES_REG_LANE, &prbs_value);
        }
    }

    PRBS_VALUE_TO_PATTERN(prbs_value, *pattern);
}

void
_ctc_at_dkit_set_prbs_en(ctc_at_dkit_serdes_dev_t* p_dev,uint8 dir, uint8 enable)
{
    /*printf("_ctc_at_dkit_set_prbs_en: serdes %u, dir %u, enable %u\n", p_dev->serdes_id, dir, enable);
    return;*/
    if(DKIT_AT_DIR_TX == dir)
    {
        if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
        {   
            if(enable)
            {
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_PHYREADY), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_EN_MODE), CTC_AT_DKIT_SERDES_REG_LANE, 2);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_EN), CTC_AT_DKIT_SERDES_REG_LANE, 1);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_RST), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                sal_task_sleep(5);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_RST), CTC_AT_DKIT_SERDES_REG_LANE, 1);
                sal_task_sleep(5);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_RST), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_PHYREADY), CTC_AT_DKIT_SERDES_REG_LANE, 1);
            }
            else
            {
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_EN), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_PHYREADY), CTC_AT_DKIT_SERDES_REG_LANE, 0);
            }
        }
        else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
        {
            if(enable)
            {
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_PHYREADY), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_EN_MODE), CTC_AT_DKIT_SERDES_REG_LANE, 2);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_EN), CTC_AT_DKIT_SERDES_REG_LANE, 1);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_RST), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                sal_task_sleep(5);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_RST), CTC_AT_DKIT_SERDES_REG_LANE, 1);
                sal_task_sleep(5);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_RST), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_PHYREADY), CTC_AT_DKIT_SERDES_REG_LANE, 1);
            }
            else
            {
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_EN), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_PHYREADY), CTC_AT_DKIT_SERDES_REG_LANE, 0);
            }
        }
    }
    else if(DKIT_AT_DIR_RX == dir) 
    {
        if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
        {   
            if(enable)
            {
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_PHYREADY), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_EN_MODE), CTC_AT_DKIT_SERDES_REG_LANE, 2);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_EN), CTC_AT_DKIT_SERDES_REG_LANE, 1);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_RST), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                sal_task_sleep(5);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_RST), CTC_AT_DKIT_SERDES_REG_LANE, 1);
                sal_task_sleep(5);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_RST), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_PHYREADY), CTC_AT_DKIT_SERDES_REG_LANE, 1);
            }
            else
            {
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_EN), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_PHYREADY), CTC_AT_DKIT_SERDES_REG_LANE, 0);
            }
        }
        else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
        {

            if(enable)
            {
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_PHYREADY), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_EN_MODE), CTC_AT_DKIT_SERDES_REG_LANE, 2);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_EN), CTC_AT_DKIT_SERDES_REG_LANE, 1);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_RST), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                sal_task_sleep(5);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_RST), CTC_AT_DKIT_SERDES_REG_LANE, 1);
                sal_task_sleep(5);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_RST), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_PHYREADY), CTC_AT_DKIT_SERDES_REG_LANE, 1);
            }
            else
            {
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_EN), CTC_AT_DKIT_SERDES_REG_LANE, 0);
                _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_PHYREADY), CTC_AT_DKIT_SERDES_REG_LANE, 0);
            }
        }
    }
}

void
_ctc_at_dkit_get_prbs_en(ctc_at_dkit_serdes_dev_t* p_dev,uint8 dir, uint32* enable)
{
    if(DKIT_AT_DIR_TX == dir)
    {
        if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
        {
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_EN), CTC_AT_DKIT_SERDES_REG_LANE, enable);
        }
        else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
        {
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_EN), CTC_AT_DKIT_SERDES_REG_LANE, enable);
        }
    }
    else if(DKIT_AT_DIR_RX == dir) 
    {
        if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
        {
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_EN), CTC_AT_DKIT_SERDES_REG_LANE, enable);
        }
        else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
        {
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_EN), CTC_AT_DKIT_SERDES_REG_LANE, enable);
        }
    }
}

int32 
_ctc_at_dkit_set_eom_en(ctc_at_dkit_serdes_dev_t* p_dev, uint8 enable)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        if(enable)
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ESM_PATH_SEL), CTC_AT_DKIT_SERDES_REG_LANE, 1);
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ESM_DFEADAPT), CTC_AT_DKIT_SERDES_REG_LANE, 0xF);
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ADAPT_EVEN), CTC_AT_DKIT_SERDES_REG_LANE, 1);
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ADAPT_ODD), CTC_AT_DKIT_SERDES_REG_LANE, 1);
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ESM_EN), CTC_AT_DKIT_SERDES_REG_LANE, 1);
            /* poll timeout : 15000 */
            if(CLI_SUCCESS != _ctc_at_dkit_serdes_poll_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_EOM_READY), CTC_AT_DKIT_SERDES_REG_LANE, 1))
            {
                return CLI_ERROR;
            }
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ESM_LPNUM), CTC_AT_DKIT_SERDES_REG_LANE, 0xFF);
        }
        else
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ESM_EN), CTC_AT_DKIT_SERDES_REG_LANE, 0);
        }
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        if(enable)
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ESM_EN), CTC_AT_DKIT_SERDES_REG_LANE, 1);
            /* poll timeout : 5000 */
            if(CLI_SUCCESS != _ctc_at_dkit_serdes_poll_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_READY), CTC_AT_DKIT_SERDES_REG_LANE, 1))
            {
                return CLI_ERROR;
            }
        }
        else
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ESM_EN), CTC_AT_DKIT_SERDES_REG_LANE, 0);
        }
    }
    return CLI_SUCCESS;
}

uint32
_ctc_at_dkit_compute_f0(ctc_at_dkit_serdes_dev_t* p_dev)
{
    uint32 data = 0;
    uint32 sum  = 0;

    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_D_T_O_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_S_T_O_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_D_T_E_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_S_T_E_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_D_M_O_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_S_M_O_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_D_M_E_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_S_M_E_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_D_B_O_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_S_B_O_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_D_B_E_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_S_B_E_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;

    /* value is returned in milli-units */
    return (sum * 1000 / 12);
}

int32
_ctc_at_dkit_compute_f0d(ctc_at_dkit_serdes_dev_t* p_dev, uint32 *top, uint32 *mid, uint32 *bot)
{
    uint32 data = 0;
    uint32 sum  = 0;

    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_D_T_O_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_S_T_O_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_D_T_E_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_S_T_E_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;

    /* value is returned in milli-units */
    *top = sum * 1000 / 4;

    sum = 0;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_D_M_O_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_S_M_O_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_D_M_E_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_S_M_E_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;

    /* value is returned in milli-units */
    *mid = sum * 1000 / 4;

    sum = 0;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_D_B_O_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_S_B_O_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_D_B_E_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_S_B_E_2C), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    sum += data;

    /* value is returned in milli-units */
    *bot = sum * 1000 / 4;

    return CLI_SUCCESS;
}

int32
_ctc_at_dkit_56g_get_trained_eye_height(ctc_at_dkit_serdes_dev_t* p_dev)
{
    uint32 prevState = 0;
    uint32 f0xData = 0;
    uint32 f0bData = 0;
    uint32 f0n1Data = 0;
    uint32 f0n2Data = 0;
    uint32 f0dData = 0;
    uint32 f0d_tData = 0;
    uint32 f0d_mData = 0;
    uint32 f0d_bData = 0;
    uint16 en = 0;
    uint16 co = 0;
    uint16 fa = 0;
    uint32 gap_ms = 100;
    uint32 times = 30;
    
    /*wait previous tx || rx train done*/
    while(times--)
    {
        _ctc_at_dkit_misc_serdes_get_rx_train_stat(p_dev, &en, &co, &fa);
        if((!en) || (en && co))
        {
            break;
        }
        sal_task_sleep(gap_ms);
    }
    times = 30;
    while(times--)
    {
        _ctc_at_dkit_misc_serdes_get_tx_train_stat(p_dev, &en, &co, &fa);
        if((!en) || (en && co))
        {
            break;
        }
        sal_task_sleep(gap_ms);
    }

    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_DFE_ADAPT), CTC_AT_DKIT_SERDES_REG_LANE, &prevState);

    /* turn off DFE continuous */
    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CLI_CMD),   CTC_AT_DKIT_SERDES_REG_LANE, 0x18);
    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CLI_ARGS),  CTC_AT_DKIT_SERDES_REG_LANE, 0x0);
    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CLI_START), CTC_AT_DKIT_SERDES_REG_LANE, 1);
    
    /* f0b */
    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CLI_CMD),   CTC_AT_DKIT_SERDES_REG_LANE, 0x19);
    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CLI_ARGS),  CTC_AT_DKIT_SERDES_REG_LANE, 0x4000);
    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CLI_START), CTC_AT_DKIT_SERDES_REG_LANE, 1);
    f0bData = _ctc_at_dkit_compute_f0(p_dev);

    /* fn1 */
    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CLI_ARGS),     CTC_AT_DKIT_SERDES_REG_LANE, 0x8000);
    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_DFE_F0X_SEL),  CTC_AT_DKIT_SERDES_REG_LANE, 0x11);
    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CLI_START),    CTC_AT_DKIT_SERDES_REG_LANE, 1);
    f0xData  = _ctc_at_dkit_compute_f0(p_dev);
    f0n1Data = f0bData - f0xData;

    /* fn2 */
    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_DFE_F0X_SEL), CTC_AT_DKIT_SERDES_REG_LANE, 0x12);
    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CLI_START),   CTC_AT_DKIT_SERDES_REG_LANE, 1);
    f0xData  = _ctc_at_dkit_compute_f0(p_dev);
    f0n2Data = f0bData - f0xData;

    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_DFE_LOAD_EN),   CTC_AT_DKIT_SERDES_REG_LANE, 0);

    /* f0d */
    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CLI_ARGS),  CTC_AT_DKIT_SERDES_REG_LANE, 0x20000);
    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CLI_START), CTC_AT_DKIT_SERDES_REG_LANE, 1);
    f0dData = _ctc_at_dkit_compute_f0(p_dev);
    _ctc_at_dkit_compute_f0d(p_dev, &f0d_tData, &f0d_mData, &f0d_bData);

    _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_DFE_LOAD_EN), CTC_AT_DKIT_SERDES_REG_LANE, 1);

    if (prevState)
    {
        /* turn on DFE continuous */
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CLI_CMD),   CTC_AT_DKIT_SERDES_REG_LANE, 0x18);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CLI_ARGS),  CTC_AT_DKIT_SERDES_REG_LANE, 0x1);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_CLI_START), CTC_AT_DKIT_SERDES_REG_LANE, 1);
    }

    CTC_DKIT_PRINT(" f0b = %d, f0n1 = %d, f0n2 = %d,  f0d = %d, f0d_t = %d, f0d_m = %d, f0d_b = %d\n", 
        f0bData, f0n1Data, f0n2Data, f0dData, f0d_tData, f0d_mData, f0d_bData);

    return CLI_SUCCESS;
}

int32 
_ctc_at_dkit_eom_eye_measpoint(ctc_at_dkit_serdes_dev_t* p_dev, uint8 tmb, int32 phase, uint8 voltage, uint32 min_samples, _dkit_at_serdes_eom_measure_t* measurement)
{
    uint32 vldCntD1Data = 0, vldCntD0Data = 0, vldCntND1Data = 0, vldCntND0Data = 0, errCntHData = 0, errCntLData = 0, errCntNHData = 0, errCntNLData = 0, pam2En = 0;
    uint32 vldCntPData_39_32 = 0, vldCntPData_31_00 = 0, vldCntNData_39_32 = 0, vldCntNData_31_00 = 0, errCntPData_31_00 = 0, errCntNData_31_00 = 0;
    uint32 totalErrCntPData = 0, totalErrCntNData = 0;
    uint64 totalVldCntPData = 0, totalVldCntNData = 0;
    int32 loop_out = 100; /* avoid while(True) when signal quality is bad */

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_PAM2_EN), CTC_AT_DKIT_SERDES_REG_LANE, &pam2En);
        if (pam2En & (DKIT_EYE_MID != tmb))
            return CLI_EOL;  /* Invalid eye */

        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ESM_PHASE), CTC_AT_DKIT_SERDES_REG_LANE, phase);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ESM_VOLTAGE), CTC_AT_DKIT_SERDES_REG_LANE, voltage);
    
        totalVldCntPData = 0;
        totalVldCntNData = 0;
        totalErrCntPData = 0;
        totalErrCntNData = 0;
    
        while (((totalVldCntPData < min_samples) || (totalVldCntNData < min_samples)) && (loop_out > 0))
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_EOM_DFE_CALL), CTC_AT_DKIT_SERDES_REG_LANE, 1);
            /* timeout 30000 */
            if(CLI_SUCCESS != _ctc_at_dkit_serdes_poll_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_EOM_DFE_CALL), CTC_AT_DKIT_SERDES_REG_LANE, 0)) return CLI_EOL;
    
            switch (tmb)
            {
                case DKIT_EYE_TOP:
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_VC_T_P_3932), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntPData_39_32);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_VC_T_P_3100), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntPData_31_00);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_VC_T_N_3932), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntNData_39_32);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_VC_T_N_3100), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntNData_31_00);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_EOM_EC_T_P), CTC_AT_DKIT_SERDES_REG_LANE, &errCntPData_31_00);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_EOM_EC_T_N), CTC_AT_DKIT_SERDES_REG_LANE, &errCntNData_31_00);
                    break;
                case DKIT_EYE_MID:
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_VC_M_P_3932), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntPData_39_32);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_VC_M_P_3100), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntPData_31_00);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_VC_M_N_3932), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntNData_39_32);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_VC_M_N_3100), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntNData_31_00);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_EOM_EC_M_P), CTC_AT_DKIT_SERDES_REG_LANE, &errCntPData_31_00);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_EOM_EC_M_N), CTC_AT_DKIT_SERDES_REG_LANE, &errCntNData_31_00);
                    break;
                case DKIT_EYE_BOT:
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_VC_B_P_3932), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntPData_39_32);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_VC_B_P_3100), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntPData_31_00);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_VC_B_N_3932), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntNData_39_32);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_VC_B_N_3100), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntNData_31_00);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_EOM_EC_B_P), CTC_AT_DKIT_SERDES_REG_LANE, &errCntPData_31_00);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_EOM_EC_B_N), CTC_AT_DKIT_SERDES_REG_LANE, &errCntNData_31_00);
                    break;
                default:
                    return CLI_EOL;  /* Invalid eye */
            }
    
            totalVldCntPData += ((uint64)vldCntPData_39_32 << 32) | vldCntPData_31_00;
            totalVldCntNData += ((uint64)vldCntNData_39_32 << 32) | vldCntNData_31_00;
            totalErrCntPData += errCntPData_31_00;
            totalErrCntNData += errCntNData_31_00;
            loop_out--;
            /*printf("    totalVldCntPData %lu, totalVldCntNData %lu, totalErrCntPData %u, totalErrCntNData %u\n", 
                totalVldCntPData, totalVldCntNData, totalErrCntPData, totalErrCntNData);*/
        }
        
        if (loop_out == 0)
        {
            CTC_DKIT_PRINT("Invalid VldCntPData and VldCntNData.\n");
            return CLI_EOL;
        }

        measurement->phase = phase;
        measurement->voltage = voltage;
        measurement->upper_bit_count = totalVldCntPData;
        measurement->upper_bit_error_count = totalErrCntPData;
        measurement->lower_bit_count = totalVldCntNData;
        measurement->lower_bit_error_count = totalErrCntNData;
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_PAM2_EN), CTC_AT_DKIT_SERDES_REG_LANE, &pam2En);
        if (pam2En & (DKIT_EYE_MID != tmb))
            return CLI_EOL;  /* Invalid eye */
        
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ESM_VOLTAGE), CTC_AT_DKIT_SERDES_REG_LANE, voltage);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ESM_PHASE), CTC_AT_DKIT_SERDES_REG_LANE, phase);
        
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_CALL_CONV), CTC_AT_DKIT_SERDES_REG_LANE, 1);
        /* timeout : 30000*/
        if(CLI_SUCCESS != _ctc_at_dkit_serdes_poll_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_CALL_CONV), CTC_AT_DKIT_SERDES_REG_LANE, 0)) return CLI_EOL;

        totalVldCntPData = 0;
        totalVldCntNData = 0;
        totalErrCntPData = 0;
        totalErrCntNData = 0;
        while (((totalVldCntPData < min_samples) || (totalVldCntNData < min_samples)) && (loop_out > 0))
        {
            _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_CALL), CTC_AT_DKIT_SERDES_REG_LANE, 1);
            /* timeout : 1000*/
            if(CLI_SUCCESS != _ctc_at_dkit_serdes_poll_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_CALL), CTC_AT_DKIT_SERDES_REG_LANE, 0)) return CLI_EOL;
        
            switch (tmb)
            {
                case DKIT_EYE_TOP:
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_D11_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntD1Data);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_D10_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntD0Data);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_N_D11_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntND1Data);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_N_D10_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntND0Data);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_TOP_H_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &errCntHData);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_TOP_L_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &errCntLData);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_N_TOP_H_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &errCntNHData);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_N_TOP_L_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &errCntNLData);
                    break;
                case DKIT_EYE_MID:
                    if (pam2En)
                    {
                        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_D11_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntD1Data);
                        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_D00_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntD0Data);
                        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_N_D11_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntND1Data);
                        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_N_D00_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntND0Data);
                    }
                    else
                    {
                        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_D10_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntD1Data);
                        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_D01_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntD0Data);
                        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_N_D10_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntND1Data);
                        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_N_D01_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntND0Data);
                    }
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_MID_H_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &errCntHData);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_MID_L_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &errCntLData);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_N_MID_H_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &errCntNHData);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_N_MID_L_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &errCntNLData);
                    /* sal_printf("    vldCntD1Data %u, vldCntD0Data %u, vldCntND1Data %u, vldCntND0Data %u, errCntHData %u, errCntLData %u, errCntNHData %u, errCntNLData %u\n", 
                        vldCntD1Data, vldCntD0Data, vldCntND1Data, vldCntND0Data, errCntHData, errCntLData, errCntNHData, errCntNLData); */
                    break;
                case DKIT_EYE_BOT:
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_D01_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntD1Data);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_D00_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntD0Data);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_N_D01_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntND1Data);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_N_D00_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &vldCntND0Data);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_BOT_H_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &errCntHData);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_BOT_L_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &errCntLData);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_N_BOT_H_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &errCntNHData);
                    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_EOM_N_BOT_L_CNT), CTC_AT_DKIT_SERDES_REG_LANE, &errCntNLData);
                default:
                    return CLI_EOL; /* Invalid eye */  
            }

            totalVldCntPData += (uint64)vldCntD1Data + vldCntD0Data;
            totalVldCntNData += (uint64)vldCntND1Data + vldCntND0Data;
            totalErrCntPData += errCntHData + errCntLData;
            totalErrCntNData += errCntNHData + errCntNLData;
            loop_out--;
        }

        if (loop_out == 0)
        {
            CTC_DKIT_PRINT("Invalid VldCntPData and VldCntNData.\n");
            return CLI_EOL;
        }

        measurement->phase = phase;
        measurement->voltage = voltage;
        measurement->upper_bit_count = totalVldCntPData;
        measurement->lower_bit_count = totalVldCntNData;
        measurement->upper_bit_error_count = totalErrCntPData;
        measurement->lower_bit_error_count = totalErrCntNData;
    }
/*
#ifdef UINT64_PRINT_FMT_LU
    sal_printf("phase %d, voltage %u, ubc %lu, lbc %lu, ube %u, lbe %u\n", measurement->phase, measurement->voltage, measurement->upper_bit_count, measurement->lower_bit_count, measurement->upper_bit_error_count, measurement->lower_bit_error_count);
#else
    sal_printf("phase %d, voltage %u, ubc %ju, lbc %ju, ube %u, lbe %u\n", measurement->phase, measurement->voltage, measurement->upper_bit_count, measurement->lower_bit_count, measurement->upper_bit_error_count, measurement->lower_bit_error_count);
#endif
*/
    return CLI_SUCCESS;
}

void
_ctc_at_dkit_get_eye_step_cnt(ctc_at_dkit_serdes_dev_t* p_dev, uint16* phase_cnt, uint16* voltage_cnt)
{
    uint8 tx_speed, rx_speed;
    uint32 mbps, pam2en;
    
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_get_txrx_rate(p_dev, &tx_speed, &rx_speed);
        (void)_ctc_at_dkit_speed_gbps_to_mbps(p_dev, rx_speed, &mbps);
        
        if (mbps >= 16000)          /* speed >= 16.0 Gbps */
        {
            *phase_cnt = 128;
        }
        else if (mbps >= 8000)      /* speed >= 8.0 Gbps */
        {
            *phase_cnt = 256;
        }
        else if (mbps >= 4000)      /* speed >= 4.0 Gbps */
        {
            *phase_cnt = 512;
        }
        else if (mbps >= 2000)      /* speed >= 2.0 Gbps */
        {
            *phase_cnt = 1024;
        }
        else
        {
            *phase_cnt = 2048;
        }
    
        *voltage_cnt = 64;
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_get_txrx_rate(p_dev, &tx_speed, &rx_speed);
        (void)_ctc_at_dkit_speed_gbps_to_mbps(p_dev, rx_speed, &mbps);
  
        if (mbps >= 80000)      /* speed >= 80.0 Gbps */
        {
            *phase_cnt = 64;
        }
        else if (mbps >= 16000) /* speed >= 16.0 Gbps */
        {
            *phase_cnt = 128;
        }
        else if (mbps >= 8000)  /* speed >= 8.0 Gbps */
        {
            *phase_cnt = 256;
        }
        else if (mbps >= 4000)  /* speed >= 4.0 Gbps */
        {
            *phase_cnt = 512;
        }
        else if (mbps >= 2000)  /* speed >= 2.0 Gbps */
        {
            *phase_cnt = 1024;
        }
        else
        {
            *phase_cnt = 2048;
        }
      
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_PAM2_EN), CTC_AT_DKIT_SERDES_REG_LANE, &pam2en);
        *voltage_cnt = (pam2en) ? DKIT_AT112G_EYE_PAM2_VOLT_STEPS : DKIT_AT112G_EYE_PAM4_VOLT_STEPS;
    }
}

static void
_ctc_at_dkit_caculate_ber(uint32 bit_err_cnt, uint64 bit_cnt, uint32 sample_cnt_scale, uint32 *nano_ber)
{
    uint64 adjusted_bit_error_count = ((uint64)bit_err_cnt) * ((uint64)sample_cnt_scale);   /* 0x3B9ACA00 == 1E+9 */
    if(0 == bit_cnt)
    {
        *nano_ber = 0xffffffff;
    }
    else
    {
        *nano_ber = (uint32)(adjusted_bit_error_count / ((uint64)bit_cnt));
    }
    /*printf("_ctc_at_dkit_caculate_ber: nano_ber %u\n", *nano_ber);*/
}

void 
_ctc_at_dkit_56g_eom_get_width_height(ctc_at_dkit_serdes_dev_t* p_dev, void* eom_margin)
{
    int32 leftEdge, rightEdge, upperEdge, lowerEdge, max_phase, min_phase, max_voltage, phase, voltage, phaseMidpoint;
    uint32 upperBER, lowerBER;
    uint16 voltage_stepcnt, phase_stepcnt;
    uint8 eye_tmb;
    uint32 ber_thrd; 
    uint32 min_samples;

    _dkit_at_serdes_56g_eom_margin_t* margin = (_dkit_at_serdes_56g_eom_margin_t*)eom_margin;
    _dkit_at_serdes_eom_measure_t measurement;
    eye_tmb = margin->eye_tmb;
    min_samples = margin->min_samples;
    ber_thrd    = margin->ber_thrd; 
    
    _ctc_at_dkit_get_eye_step_cnt(p_dev, &phase_stepcnt, &voltage_stepcnt);
    max_phase = phase_stepcnt / 2;
    min_phase = -phase_stepcnt / 2;
    max_voltage = voltage_stepcnt;

    /* Set default edge values */
    leftEdge = min_phase;
    rightEdge = max_phase;
    upperEdge = -max_voltage;
    lowerEdge = max_voltage - 1;

    if(CLI_SUCCESS != _ctc_at_dkit_set_eom_en(p_dev, 1))
    {
        return;
    }
    
    /* Scan Left */
    for (phase = 0; phase < max_phase; phase++)
    {
        if(CLI_SUCCESS != _ctc_at_dkit_eom_eye_measpoint(p_dev, eye_tmb, phase, 0, min_samples, &measurement))
        {
            return;
        }
        
        if (0 == phase)
        {
            margin->sample_count = (uint32)measurement.upper_bit_count;
        }

        /* Stop because no bits were read */
        if ((0 == measurement.upper_bit_count) || (0 == measurement.lower_bit_count))
        {
            leftEdge = phase;
            break;
        }

        /* Stop because BER was too high */
        _ctc_at_dkit_caculate_ber(measurement.upper_bit_error_count, measurement.upper_bit_count, min_samples, &upperBER);
        _ctc_at_dkit_caculate_ber(measurement.lower_bit_error_count, measurement.lower_bit_count, min_samples, &lowerBER);
        /*printf("scan left: phase %d, voltage %u, upperBER %u, lowerBER %u, ber_thrd %u\n", phase, 0, upperBER, lowerBER, ber_thrd);*/
        if ((ber_thrd < upperBER) || (ber_thrd < lowerBER))
        {
            leftEdge = phase;
            break;
        }
    }

    /* Scan Right */
    for (phase = -1; phase > min_phase; phase--)
    {
        if(CLI_SUCCESS != _ctc_at_dkit_eom_eye_measpoint(p_dev, eye_tmb, phase, 0, min_samples, &measurement))
        {
            return;
        }

        /* Stop because no bits were read */
        if ((0 == measurement.upper_bit_count) || (0 == measurement.lower_bit_count))
        {
            rightEdge = phase;
            break;
        }

        /* Stop because BER was too high */
        _ctc_at_dkit_caculate_ber(measurement.upper_bit_error_count, measurement.upper_bit_count, min_samples, &upperBER);
        _ctc_at_dkit_caculate_ber(measurement.lower_bit_error_count, measurement.lower_bit_count, min_samples, &lowerBER);
        /*printf("scan right: phase %d, voltage %u, upperBER %u, lowerBER %u, ber_thrd %u\n", phase, 0, upperBER, lowerBER, ber_thrd);*/
        if ((ber_thrd < upperBER) || (ber_thrd < lowerBER))
        {
            rightEdge = phase;
            break;
        }
    }

    /* Default if either edge did not update */
    if ((leftEdge == min_phase) || (rightEdge == max_phase))
    {
        leftEdge = max_phase;
        rightEdge = min_phase;
    }

    phaseMidpoint = (leftEdge - rightEdge) / 2 + rightEdge;

    /* Scan up and down */
    for (voltage = 0; voltage < max_voltage; voltage++)
    {
        if(CLI_SUCCESS != _ctc_at_dkit_eom_eye_measpoint(p_dev, eye_tmb, phaseMidpoint, (uint8)voltage, min_samples, &measurement))
        {
            return;
        }

        /* Update once */
        while (upperEdge == -max_voltage)
        {
            /* Update because no bits read */
            if (0 == measurement.upper_bit_count)
            {
                upperEdge = voltage;
                break;
            }

            /* Update because BER was too high */
            _ctc_at_dkit_caculate_ber(measurement.upper_bit_error_count, measurement.upper_bit_count, min_samples, &upperBER);
            /*printf("scan up: phase %d, voltage %u, upperBER %u, ber_thrd %u\n", phaseMidpoint, voltage, upperBER, ber_thrd);*/
            if (ber_thrd < upperBER)
            {
                upperEdge = voltage;
            }
            break;
        }

        /* Update once */
        while (lowerEdge == (max_voltage - 1))
        {
            /* Update because no bits read */
            if (0 == measurement.lower_bit_count)
            {
                lowerEdge = -voltage;
                break;
            }

            /* Update because BER was too high */
            _ctc_at_dkit_caculate_ber(measurement.lower_bit_error_count, measurement.lower_bit_count, min_samples, &lowerBER);
            /*printf("scan down: phase %d, voltage %u, lowerBER %u, ber_thrd %u\n", phaseMidpoint, voltage, lowerBER, ber_thrd);*/
            if (ber_thrd < lowerBER)
            {
                lowerEdge = -voltage;
            }
            break;
        }

        /* Stop when both edges are found */
        if ((upperEdge != -max_voltage) && (lowerEdge != (max_voltage - 1)))
        {
            break;
        }
    }

    /* Default if either edge did not update */
    if ((upperEdge == -max_voltage) || (lowerEdge == (max_voltage - 1)))
    {
        upperEdge = max_voltage - 1;
        lowerEdge = 1 - max_voltage;
    }

    margin->width = (uint16)((leftEdge == rightEdge) ? 0 : leftEdge - rightEdge);
    if (upperEdge == lowerEdge)
    {
        margin->height_upper = 0;
        margin->height_lower = 0;
    }
    else
    {
        margin->height_upper = (uint16)upperEdge;
        margin->height_lower = (uint16)((lowerEdge < 0) ? -lowerEdge : lowerEdge);
    }
    
    if(CLI_SUCCESS != _ctc_at_dkit_set_eom_en(p_dev, 0))
    {
        return;
    }
}

int32 
_ctc_at_dkit_112g_eom_get_width_height(ctc_at_dkit_serdes_dev_t* p_dev, void* eom_margin)
{
    int32 leftEdge, rightEdge, upperEdge, lowerEdge, max_phase, min_phase, max_voltage, phase, voltage;
    uint16 voltage_stepcnt, phase_stepcnt;
    uint16 width_left;
    uint16 width_right;
    uint32 min_samples;
    uint8 eye_tmb;
    uint8 modulation;
    int32 phase_mid_point;
    uint32 upper_ber, lower_ber;
    uint32 ber_thrd;

    _dkit_at_serdes_eom_measure_t      measurement;
    _dkit_at_serdes_112g_eom_margin_t* margin = (_dkit_at_serdes_112g_eom_margin_t*)eom_margin;

    modulation = _ctc_at_dkit_get_serdes_modulation_mode(p_dev);

    eye_tmb = margin->eye_tmb;
    min_samples = margin->min_samples;
    ber_thrd = margin->ber_thrd;

    if ((CTC_DKIT_AT_SERDES_NRZ_MODE == modulation) & (DKIT_EYE_TOP != eye_tmb))
    {
        return CLI_EOL;  /* Invalid eye */
    }
    
    _ctc_at_dkit_get_eye_step_cnt(p_dev, &phase_stepcnt, &voltage_stepcnt);
    max_phase = phase_stepcnt / 2;
    min_phase = -phase_stepcnt / 2;
    max_voltage = voltage_stepcnt;

    /* Set default edge values */
    leftEdge = min_phase;
    rightEdge = max_phase;
    upperEdge = -max_voltage;
    lowerEdge = max_voltage - 1;

    if(CLI_SUCCESS != _ctc_at_dkit_set_eom_en(p_dev, 1))
    {
        return CLI_ERROR;
    }
    
    /* Scan Left */
    for (phase = 0; phase < max_phase; phase++)
    {
        if(CLI_SUCCESS != _ctc_at_dkit_eom_eye_measpoint(p_dev, eye_tmb, phase, 0, min_samples, &measurement))
        {
            return CLI_EOL;
        }

        if (0 == phase)
        {
            margin->sample_count = (uint32)measurement.upper_bit_count;
        }

        /* Stop when no bits read or error */
        if ((0 == measurement.upper_bit_count) || (0 == measurement.lower_bit_count))
        {
            leftEdge = phase;
            break;
        }

        /* Stop because BER was too high */
        (void)_ctc_at_dkit_caculate_ber(measurement.upper_bit_error_count, measurement.upper_bit_count, min_samples, &upper_ber);
        (void)_ctc_at_dkit_caculate_ber(measurement.lower_bit_error_count, measurement.lower_bit_count, min_samples, &lower_ber);
        if ((ber_thrd < upper_ber) || (ber_thrd < lower_ber))
        {
            leftEdge = phase;
            break;
        }
    }

    /* Scan Right */
    for (phase = -1; phase > min_phase; phase--)
    {
        if(CLI_SUCCESS != _ctc_at_dkit_eom_eye_measpoint(p_dev, eye_tmb, phase, 0, min_samples, &measurement))
        {
            return CLI_EOL;
        }

        /* Stop because no bits were read */
        if ((0 == measurement.upper_bit_count) || (0 == measurement.lower_bit_count))
        {
            rightEdge = phase;
            break;
        }

        /* Stop because BER was too high */
        (void)_ctc_at_dkit_caculate_ber(measurement.upper_bit_error_count, measurement.upper_bit_count, min_samples, &upper_ber);
        (void)_ctc_at_dkit_caculate_ber(measurement.lower_bit_error_count, measurement.lower_bit_count, min_samples, &lower_ber);
        if ((ber_thrd < upper_ber) || (ber_thrd < lower_ber))
        {
            rightEdge = phase;
            break;
        }
    }

    /* Default if either edge did not update */
    if ((leftEdge == min_phase) || (rightEdge == max_phase))
    {
        leftEdge = max_phase;
        rightEdge = min_phase;
    }
   
    phase_mid_point = (leftEdge - rightEdge) / 2 + rightEdge;

    for (voltage = 0; voltage < max_voltage; voltage++)
    {
        if(CLI_SUCCESS != _ctc_at_dkit_eom_eye_measpoint(p_dev, eye_tmb, phase_mid_point, (uint8)voltage, min_samples, &measurement))
        {
            return CLI_EOL;
        }

        /* Update once when no bits read or error */
        if (0 == measurement.upper_bit_count)
        {
            upperEdge = voltage;
        }

        /* Update once when no bits read or error */
        (void)_ctc_at_dkit_caculate_ber(measurement.upper_bit_error_count, measurement.upper_bit_count, min_samples, &upper_ber);
        if (ber_thrd < upper_ber)
        {
            upperEdge = voltage;
        }

        /* Update once when no bits read or error */
        if (0 == measurement.lower_bit_count)
        {
            lowerEdge = -voltage;
        }

        /* Update once when no bits read or error */
        (void)_ctc_at_dkit_caculate_ber(measurement.lower_bit_error_count, measurement.lower_bit_count, min_samples, &lower_ber);
        if (ber_thrd < lower_ber)
        {
            lowerEdge = -voltage;
        }

        /* Stop when both edges are found */
        if ((upperEdge != -max_voltage) && (lowerEdge != (max_voltage - 1)))
        {
            break;
        }
    }
    
    /* Default if either edge did not update */
    if ((upperEdge == -max_voltage) || (lowerEdge == (max_voltage - 1)))
    {
         upperEdge = max_voltage - 1;
         lowerEdge = 1 - max_voltage;
    }
    
    width_left = (int16)((leftEdge == rightEdge) ? 0 : leftEdge);
    width_right = (int16)((leftEdge == rightEdge) ? 0 : -rightEdge);
    margin->width = width_left + width_right;
    
    if (upperEdge == lowerEdge)
    {
        margin->height_upper = 0;
        margin->height_lower = 0;
    }
    else
    {
        margin->height_upper = (uint16)upperEdge;
        margin->height_lower = (uint16)((lowerEdge < 0) ? -lowerEdge : lowerEdge);
    }

    if(CLI_SUCCESS != _ctc_at_dkit_set_eom_en(p_dev, 0))
    {
        return CLI_ERROR;
    }

    return CLI_SUCCESS;
}

void
_ctc_at_dkit_eom_get_width_height(ctc_at_dkit_serdes_dev_t* p_dev, void* eom_margin)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_56g_eom_get_width_height(p_dev, eom_margin);        
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        (void)_ctc_at_dkit_112g_eom_get_width_height(p_dev, eom_margin);        
    }
}

void
_ctc_at_dkit_get_dfe_f0(ctc_at_dkit_serdes_dev_t* p_dev, uint32* table)
{
    uint32 i, tableSelData, resData, resDoubleData;

    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_F0_DC_SHIFT), CTC_AT_DKIT_SERDES_REG_LANE, &tableSelData);
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_DFE_RES_F0), CTC_AT_DKIT_SERDES_REG_LANE, &resData);
    _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_DFE_F0_RES_DOUBLE), CTC_AT_DKIT_SERDES_REG_LANE, &resDoubleData);

    for (i = 0; i < 64; i++)
    {
        if (1 == resDoubleData)
            table[i] = DKIT_AT56G_DFE_F0_TABLE[tableSelData][resData][i] * 2;
        else
            table[i] = DKIT_AT56G_DFE_F0_TABLE[tableSelData][resData][i];
    }
}

int32
_ctc_at_dkit_eom_convert_width_height(ctc_at_dkit_serdes_dev_t* p_dev, uint16 width, uint16 height_upper, uint16 height_lower, uint32* width_m_ui,
                                                    uint32* height100uVUpper, uint32* height100uVLower)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        uint16 phaseStepCount, voltageStepCount;
        uint32 table[64];
    
        *width_m_ui = 0;
        *height100uVUpper = 0;
        *height100uVLower = 0;
    
        if (0 == width) return CLI_EOL; /* Division by 0 Error */
    
        /* Convert width */
        _ctc_at_dkit_get_eye_step_cnt(p_dev, &phaseStepCount, &voltageStepCount);
        *width_m_ui = (uint32)width * 1000 / phaseStepCount;
    
        /* Convert height */
        _ctc_at_dkit_get_dfe_f0(p_dev, &table[0]);
        
        *height100uVUpper = table[height_upper];
        *height100uVLower = table[height_lower];
    }
    else 
    {
        /* 112g current not support */
    }
    
    return CLI_SUCCESS;
}

int32
_ctc_at_dkit_eom_get_eye_data(ctc_at_dkit_serdes_dev_t* p_dev, uint8 tmb, uint32 min_samples, 
                                        uint32 ber_thrd, uint8 eomStatsMode, void* p_eye_data)
{
    _dkit_at_serdes_eom_measure_t measurement;
    _dkit_at_serdes_56g_eom_data_t*   p_eye_data_56g;   
    _dkit_at_serdes_112g_eom_data_t*  p_eye_data_112g;
    uint32 leftEdgeIdx, rightEdgeIdx, upperEdgeIdx, lowerEdgeIdx, phaseCenterIdx, voltageCenterIdx, upperBer, lowerBer;
    int32 upperEdge, lowerEdge, leftMaxEdge, rightMaxEdge, upperMaxEdge, lowerMaxEdge, phase, voltage, upperVoltage, lowerVoltage, leftInnerEdge, rightInnerEdge;
    uint16 phase_stepcnt = 0, voltage_stepcnt = 0;

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_get_eye_step_cnt(p_dev, &phase_stepcnt, &voltage_stepcnt);
    
        if (!p_eye_data)
        {
            CTC_DKIT_PRINT("eyeRawDataPtr is NULL\n");
            return CLI_EOL;
        }

        p_eye_data_56g = (_dkit_at_serdes_56g_eom_data_t*) p_eye_data;

        p_eye_data_56g->oneUIwidth = phase_stepcnt;
        
        phaseCenterIdx = DKIT_AT56G_EYE_MAX_PHASE_LEVEL / 2;
        voltageCenterIdx = voltage_stepcnt - 1;
        leftEdgeIdx = phaseCenterIdx - (phase_stepcnt / 2);
        rightEdgeIdx = phaseCenterIdx + (phase_stepcnt / 2) - 1;
        upperEdgeIdx = voltageCenterIdx - (voltage_stepcnt - 1);
        lowerEdgeIdx = voltageCenterIdx + (voltage_stepcnt - 1);
    
        leftMaxEdge = phase_stepcnt / 2;
        rightMaxEdge = 1 - (phase_stepcnt / 2);
        upperMaxEdge = voltage_stepcnt - 1;
        lowerMaxEdge = 1 - voltage_stepcnt;
        upperEdge = 0;
        lowerEdge = 0;

        if(CLI_SUCCESS != _ctc_at_dkit_set_eom_en(p_dev, 1))
        {
            return CLI_ERROR;
        }

        if(CLI_SUCCESS != _ctc_at_dkit_eom_eye_measpoint(p_dev, tmb, 0, 0, min_samples, &measurement))
        {
            return CLI_EOL;
        }
        p_eye_data_56g->sampleCount = (uint32)measurement.upper_bit_count;

         if (0 == measurement.upper_bit_count || 0 == measurement.lower_bit_count)
        {
            (void)_ctc_at_dkit_set_eom_en(p_dev, 0);
            CTC_DKIT_PRINT("_ctc_at_dkit_eom_get_eye_data: Total Bit Count == 0 at (Phase: 0, Voltage: 0)\n");
            return CLI_EOL;
        }

        _ctc_at_dkit_caculate_ber(measurement.upper_bit_error_count, measurement.upper_bit_count, min_samples, &upperBer);
        _ctc_at_dkit_caculate_ber(measurement.lower_bit_error_count, measurement.lower_bit_count, min_samples, &lowerBer);
        if ((ber_thrd < upperBer) || (ber_thrd < lowerBer))
        {
            (void)_ctc_at_dkit_set_eom_en(p_dev, 0);
            CTC_DKIT_PRINT("_ctc_at_dkit_eom_get_eye_data: BER > ber_thrd at (Phase: 0, Voltage: 0)\n");
            return CLI_EOL;
        }
        
        /* Left Sweep from Phase 0 with Voltage Sweep */
        leftInnerEdge = leftMaxEdge;
        for (phase = 0; phase <= leftMaxEdge; phase++)
        {
            upperVoltage = lowerMaxEdge;
            lowerVoltage = upperMaxEdge;
            for (voltage = 0; voltage <= upperMaxEdge; voltage++)
            {
                if(CLI_SUCCESS != _ctc_at_dkit_eom_eye_measpoint(p_dev, tmb, phase, (uint8)voltage, min_samples, &measurement))
                {
                    return CLI_EOL;
                }

                p_eye_data_56g->eyeRawData[phaseCenterIdx - phase][voltageCenterIdx + voltage] = measurement.lower_bit_error_count;
                p_eye_data_56g->eyeRawData[phaseCenterIdx - phase][voltageCenterIdx - voltage] = measurement.upper_bit_error_count;

                _ctc_at_dkit_caculate_ber(measurement.upper_bit_error_count, measurement.upper_bit_count, min_samples, &upperBer);
                _ctc_at_dkit_caculate_ber(measurement.lower_bit_error_count, measurement.lower_bit_count, min_samples, &lowerBer);
                if ((ber_thrd < upperBer) || (ber_thrd < lowerBer))
                {
                    if ((upperVoltage == lowerMaxEdge) && ((0 == measurement.upper_bit_count) || (ber_thrd < upperBer)))
                        upperVoltage = voltage; /* found upper edge */

                    if ((lowerVoltage == upperMaxEdge) && ((0 == measurement.lower_bit_count) || (ber_thrd < lowerBer)))
                        lowerVoltage = -voltage; /* found lower edge */
                }

                if ((phase < leftInnerEdge) && ((0 == upperVoltage) || (0 == lowerVoltage)))
                    leftInnerEdge = phase;

                /* Measure only voltage 0 in eomStatsMode */
                if (eomStatsMode)
                    break;

                if (((upperVoltage != lowerMaxEdge) && (lowerVoltage != upperMaxEdge)))
                    break;
            }

            /* Measure full UI in eomStatsMode */
            if (eomStatsMode)
                continue;

            if (upperVoltage > upperEdge)
                upperEdge = upperVoltage;

            if (lowerVoltage < lowerEdge)
                lowerEdge = lowerVoltage;

            /* Stop when (phase, 0) exceeds BER threshold */
            if (0 == upperVoltage && 0 == lowerVoltage)
            {
                leftEdgeIdx = phaseCenterIdx - phase;
                break;
            }
        }

        /* Right Sweep from Phase -1 with Voltage Sweep */
        rightInnerEdge = rightMaxEdge;
        for (phase = -1; phase >= rightMaxEdge; phase--)
        {
            upperVoltage = lowerMaxEdge;
            lowerVoltage = upperMaxEdge;
            for (voltage = 0; voltage <= upperMaxEdge; voltage++)
            {
                if(CLI_SUCCESS != _ctc_at_dkit_eom_eye_measpoint(p_dev, tmb, phase, (uint8)voltage, min_samples, &measurement))
                {
                    return CLI_EOL;
                }

                p_eye_data_56g->eyeRawData[phaseCenterIdx - phase][voltageCenterIdx + voltage] = measurement.lower_bit_error_count;
                p_eye_data_56g->eyeRawData[phaseCenterIdx - phase][voltageCenterIdx - voltage] = measurement.upper_bit_error_count;

                _ctc_at_dkit_caculate_ber(measurement.upper_bit_error_count, measurement.upper_bit_count, min_samples, &upperBer);
                _ctc_at_dkit_caculate_ber(measurement.lower_bit_error_count, measurement.lower_bit_count, min_samples, &lowerBer);
                if ((ber_thrd < upperBer) || (ber_thrd < lowerBer))
                {
                    if ((upperVoltage == lowerMaxEdge) && ((0 == measurement.upper_bit_count) || (ber_thrd < upperBer)))
                        upperVoltage = voltage; /* found upper edge */

                    if ((lowerVoltage == upperMaxEdge) && ((0 == measurement.lower_bit_count) || (ber_thrd < lowerBer)))
                        lowerVoltage = -voltage; /* found lower edge */
                }

                if ((phase > rightInnerEdge) && ((0 == upperVoltage) || (0 == lowerVoltage)))
                    rightInnerEdge = phase;

                /* Measure only voltage 0 in eomStatsMode */
                if (eomStatsMode)
                    break;

                if (((upperVoltage != lowerMaxEdge) && (lowerVoltage != upperMaxEdge)))
                    break;
            }

            /* Measure full UI in eomStatsMode */
            if (eomStatsMode)
                continue;

            if (upperVoltage > upperEdge)
                upperEdge = upperVoltage;

            if (lowerVoltage < lowerEdge)
                lowerEdge = lowerVoltage;

            /* Stop when (phase, 0) exceeds BER threshold */
            if (0 == upperVoltage && 0 == lowerVoltage)
            {
                rightEdgeIdx = phaseCenterIdx - phase;
                break;
            }
        }

        p_eye_data_56g->relativeCenter = phaseCenterIdx - ((leftInnerEdge - rightInnerEdge) / 2 + rightInnerEdge);
        if (eomStatsMode)
        {
            /* Full Voltage Sweep at Phase Midpoint */
            phase = (leftInnerEdge - rightInnerEdge) / 2 + rightInnerEdge;
            for (voltage = 0; voltage <= upperMaxEdge; voltage++)
            {
                if(CLI_SUCCESS != _ctc_at_dkit_eom_eye_measpoint(p_dev, tmb, phase, (uint8)voltage, min_samples, &measurement))
                {
                    return CLI_EOL;
                }

                p_eye_data_56g->eyeRawData[phaseCenterIdx - phase][voltageCenterIdx + voltage] = measurement.lower_bit_error_count;
                p_eye_data_56g->eyeRawData[phaseCenterIdx - phase][voltageCenterIdx - voltage] = measurement.upper_bit_error_count;
            }
            upperEdgeIdx = voltageCenterIdx - upperMaxEdge;
            lowerEdgeIdx = voltageCenterIdx - lowerMaxEdge;
            leftEdgeIdx = phaseCenterIdx - leftMaxEdge;
            rightEdgeIdx = phaseCenterIdx - rightMaxEdge;
        }
        else
        {
            upperEdgeIdx = voltageCenterIdx - upperEdge;
            lowerEdgeIdx = voltageCenterIdx - lowerEdge;
        }

        _ctc_at_dkit_get_dfe_f0(p_dev, &p_eye_data_56g->mv_table[0]);       
        _ctc_at_dkit_set_eom_en(p_dev, 0);

        p_eye_data_56g->leftEdge = leftEdgeIdx;
        p_eye_data_56g->rightEdge = rightEdgeIdx;
        p_eye_data_56g->upperEdge = upperEdgeIdx;
        p_eye_data_56g->lowerEdge = lowerEdgeIdx;
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        if (!p_eye_data)
        {
            CTC_DKIT_PRINT("eyeRawDataPtr is NULL\n");
            return CLI_EOL;
        }

        p_eye_data_112g = (_dkit_at_serdes_112g_eom_data_t*) p_eye_data;

        phaseCenterIdx = DKIT_AT112G_EYE_MAX_PHASE_LEVEL / 2;
        voltageCenterIdx = DKIT_AT112G_EYE_PAM2_VOLT_STEPS - 1;
        leftEdgeIdx = phaseCenterIdx - (phase_stepcnt / 2);
        rightEdgeIdx = phaseCenterIdx + (phase_stepcnt / 2) - 1;
        upperEdgeIdx = voltageCenterIdx - (voltage_stepcnt - 1);
        lowerEdgeIdx = voltageCenterIdx + (voltage_stepcnt - 1);

        leftMaxEdge = phase_stepcnt / 2;
        rightMaxEdge = 1 - (phase_stepcnt / 2);
        upperMaxEdge = voltage_stepcnt - 1;
        lowerMaxEdge = 1 - voltage_stepcnt;
        upperEdge = 0;
        lowerEdge = 0;

        (void)_ctc_at_dkit_set_eom_en(p_dev, 1);

        /* Check (0, 0) */
        if(CLI_SUCCESS != _ctc_at_dkit_eom_eye_measpoint(p_dev, tmb, 0, 0, min_samples, &measurement))
        {
            return CLI_EOL;
        }
        p_eye_data_112g->sampleCount = (uint32)measurement.upper_bit_count;

        if (0 == measurement.upper_bit_count || 0 == measurement.lower_bit_count)
        {
            (void)_ctc_at_dkit_set_eom_en(p_dev, 0);
            CTC_DKIT_PRINT("_ctc_at_dkit_eom_get_eye_data: Total Bit Count == 0 at (Phase: 0, Voltage: 0)\n");
            return CLI_EOL;
        }

        (void)_ctc_at_dkit_caculate_ber(measurement.upper_bit_error_count, measurement.upper_bit_count, min_samples, &upperBer);
        (void)_ctc_at_dkit_caculate_ber(measurement.lower_bit_error_count, measurement.lower_bit_count, min_samples, &lowerBer);
        if ((ber_thrd < upperBer) || (ber_thrd < lowerBer))
        {
            (void)_ctc_at_dkit_set_eom_en(p_dev, 0);
            CTC_DKIT_PRINT("_ctc_at_dkit_eom_get_eye_data: BER > ber_thrd at (Phase: 0, Voltage: 0)\n");
            return CLI_EOL;
        }

        /* Left Sweep from Phase 0 with Voltage Sweep */
        leftInnerEdge = leftMaxEdge;
        for (phase = 0; phase <= leftMaxEdge; phase++)
        {
            upperVoltage = lowerMaxEdge;
            lowerVoltage = upperMaxEdge;
            for (voltage = 0; voltage <= upperMaxEdge; voltage++)
            {
                if(CLI_SUCCESS != _ctc_at_dkit_eom_eye_measpoint(p_dev, tmb, phase, (uint8)voltage, min_samples, &measurement))
                {
                    return CLI_EOL;
                }

                p_eye_data_112g->eyeRawData[phaseCenterIdx - phase][voltageCenterIdx + voltage] = measurement.lower_bit_error_count;
                p_eye_data_112g->eyeRawData[phaseCenterIdx - phase][voltageCenterIdx - voltage] = measurement.upper_bit_error_count;

                (void)_ctc_at_dkit_caculate_ber(measurement.upper_bit_error_count, measurement.upper_bit_count, min_samples, &upperBer);
                (void)_ctc_at_dkit_caculate_ber(measurement.lower_bit_error_count, measurement.lower_bit_count, min_samples, &lowerBer);
                if ((ber_thrd < upperBer) || (ber_thrd < lowerBer))
                {
                    if ((upperVoltage == lowerMaxEdge) && ((0 == measurement.upper_bit_count) || (ber_thrd < upperBer)))
                        upperVoltage = voltage; /* found upper edge */

                    if ((lowerVoltage == upperMaxEdge) && ((0 == measurement.lower_bit_count) || (ber_thrd < lowerBer)))
                        lowerVoltage = -voltage; /* found lower edge */
                }

                if ((phase < leftInnerEdge) && ((0 == upperVoltage) || (0 == lowerVoltage)))
                    leftInnerEdge = phase;

                /* Measure only voltage 0 in eomStatsMode */
                if (eomStatsMode)
                    break;

                if (((upperVoltage != lowerMaxEdge) && (lowerVoltage != upperMaxEdge)))
                    break;
            }

            /* Measure full UI in eomStatsMode */
            if (eomStatsMode)
                continue;

            if (upperVoltage > upperEdge)
                upperEdge = upperVoltage;

            if (lowerVoltage < lowerEdge)
                lowerEdge = lowerVoltage;

            /* Stop when (phase, 0) exceeds BER threshold */
            if (0 == upperVoltage && 0 == lowerVoltage)
            {
                leftEdgeIdx = phaseCenterIdx - phase;
                break;
            }
        }

        /* Right Sweep from Phase -1 with Voltage Sweep */
        rightInnerEdge = rightMaxEdge;
        for (phase = -1; phase >= rightMaxEdge; phase--)
        {
            upperVoltage = lowerMaxEdge;
            lowerVoltage = upperMaxEdge;
            for (voltage = 0; voltage <= upperMaxEdge; voltage++)
            {
                if(CLI_SUCCESS != _ctc_at_dkit_eom_eye_measpoint(p_dev, tmb, phase, (uint8)voltage, min_samples, &measurement))
                {
                    return CLI_EOL;
                }

                p_eye_data_112g->eyeRawData[phaseCenterIdx - phase][voltageCenterIdx + voltage] = measurement.lower_bit_error_count;
                p_eye_data_112g->eyeRawData[phaseCenterIdx - phase][voltageCenterIdx - voltage] = measurement.upper_bit_error_count;

                (void)_ctc_at_dkit_caculate_ber(measurement.upper_bit_error_count, measurement.upper_bit_count, min_samples, &upperBer);
                (void)_ctc_at_dkit_caculate_ber(measurement.lower_bit_error_count, measurement.lower_bit_count, min_samples, &lowerBer);
                if ((ber_thrd < upperBer) || (ber_thrd < lowerBer))
                {
                    if ((upperVoltage == lowerMaxEdge) && ((0 == measurement.upper_bit_count) || (ber_thrd < upperBer)))
                        upperVoltage = voltage; /* found upper edge */

                    if ((lowerVoltage == upperMaxEdge) && ((0 == measurement.lower_bit_count) || (ber_thrd < lowerBer)))
                        lowerVoltage = -voltage; /* found lower edge */
                }

                if ((phase > rightInnerEdge) && ((0 == upperVoltage) || (0 == lowerVoltage)))
                    rightInnerEdge = phase;

                /* Measure only voltage 0 in eomStatsMode */
                if (eomStatsMode)
                    break;

                if (((upperVoltage != lowerMaxEdge) && (lowerVoltage != upperMaxEdge)))
                    break;
            }

            /* Measure full UI in eomStatsMode */
            if (eomStatsMode)
                continue;

            if (upperVoltage > upperEdge)
                upperEdge = upperVoltage;

            if (lowerVoltage < lowerEdge)
                lowerEdge = lowerVoltage;

            /* Stop when (phase, 0) exceeds BER threshold */
            if (0 == upperVoltage && 0 == lowerVoltage)
            {
                rightEdgeIdx = phaseCenterIdx - phase;
                break;
            }
        }

        p_eye_data_112g->relativeCenter = phaseCenterIdx - ((leftInnerEdge - rightInnerEdge) / 2 + rightInnerEdge);
        if (eomStatsMode)
        {
            /* Full Voltage Sweep at Phase Midpoint */
            phase = (leftInnerEdge - rightInnerEdge) / 2 + rightInnerEdge;
            for (voltage = 0; voltage <= upperMaxEdge; voltage++)
            {
                if(CLI_SUCCESS != _ctc_at_dkit_eom_eye_measpoint(p_dev, tmb, phase, (uint8)voltage, min_samples, &measurement))
                {
                    return CLI_EOL;
                }

                p_eye_data_112g->eyeRawData[phaseCenterIdx - phase][voltageCenterIdx + voltage] = measurement.lower_bit_error_count;
                p_eye_data_112g->eyeRawData[phaseCenterIdx - phase][voltageCenterIdx - voltage] = measurement.upper_bit_error_count;
            }
            upperEdgeIdx = voltageCenterIdx - upperMaxEdge;
            lowerEdgeIdx = voltageCenterIdx - lowerMaxEdge;
            leftEdgeIdx = phaseCenterIdx - leftMaxEdge;
            rightEdgeIdx = phaseCenterIdx - rightMaxEdge;
        }
        else
        {
            upperEdgeIdx = voltageCenterIdx - upperEdge;
            lowerEdgeIdx = voltageCenterIdx - lowerEdge;
        }

        (void)_ctc_at_dkit_set_eom_en(p_dev, 0);

        p_eye_data_112g->leftEdge = leftEdgeIdx;
        p_eye_data_112g->rightEdge = rightEdgeIdx;
        p_eye_data_112g->upperEdge = upperEdgeIdx;
        p_eye_data_112g->lowerEdge = lowerEdgeIdx;
    }
    
    return CLI_SUCCESS;
}

int32
_ctc_at_dkit_plot_eye_data
(
    int32* eyeRawData,
    uint32 leftEdgeIdx,
    uint32 rightEdgeIdx,
    uint32 phaseCenterIdx, 
    uint32 phaseStepSize,  
    uint32 upperEdgeIdx,   
    uint32 lowerEdgeIdx,
    uint32 voltageCenterIdx, 
    uint32 voltageStepSize,  
    uint32 sampleCount,      
    uint32 arrayShift,
    uint32 min_samples, 
    uint32 min_samples_sub,
    uint32 berThreshold,     
    uint32 berThreshold_sub,  
    uint32*dfeRes,
    uint32 dfeResFactor_mV   
)
{
    uint32 phaseIdx, voltageIdx, error, threshold1, threshold2, mV, mVPrecision, mVIndex;
    char mVString[8];

    if (!eyeRawData)
    {
        CTC_DKIT_PRINT("plotEyeData: eyeRawData is NULL\n");
        return CLI_EOL;
    }

    /* Calculate Actual Error Threshold */
    threshold1 = (uint64)(((uint64)sampleCount * (uint64)berThreshold) / (uint64)min_samples);
    threshold2 = (uint64)(((uint64)sampleCount * (uint64)berThreshold_sub) / (uint64)min_samples_sub);

    /* Adjust Range based on StepSize to show Lines */
    if (voltageStepSize > 1)
    {
        upperEdgeIdx += (voltageCenterIdx - upperEdgeIdx) % voltageStepSize;
        lowerEdgeIdx -= (lowerEdgeIdx - voltageCenterIdx) % voltageStepSize;
    }
    if (phaseStepSize > 1)
    {
        leftEdgeIdx += (phaseCenterIdx - leftEdgeIdx) % phaseStepSize;
        rightEdgeIdx -= (rightEdgeIdx - phaseCenterIdx) % phaseStepSize;
    }
    
    for (voltageIdx = upperEdgeIdx; voltageIdx <= lowerEdgeIdx; voltageIdx += voltageStepSize)
    {
        /* Printing of mV Axis */
        if (dfeRes != NULL)
        {
            mVIndex = (voltageCenterIdx < voltageIdx) ? voltageIdx - voltageCenterIdx : voltageCenterIdx - voltageIdx;
            mV = dfeRes[mVIndex] / dfeResFactor_mV;
            mVPrecision = ((dfeRes[mVIndex] * 10) / dfeResFactor_mV) % 10;
            if (voltageCenterIdx == voltageIdx)
                sal_sprintf(mVString, "       ");
            else if (voltageCenterIdx < voltageIdx)
                sal_sprintf(mVString, "-%3d.%d ", mV, mVPrecision);
            else
                sal_sprintf(mVString, " %3d.%d ", mV, mVPrecision);
            CTC_DKIT_PRINT(mVString);
        }

        for (phaseIdx = leftEdgeIdx; phaseIdx <= rightEdgeIdx; phaseIdx += phaseStepSize)
        {
            /* Formatting of Plot */
            if (voltageIdx == voltageCenterIdx)             /* Print X-Axis */
            {
                CTC_DKIT_PRINT("-");
                continue;
            }
            else if (phaseIdx == phaseCenterIdx)           /* Print Y-Axis */
            {
                CTC_DKIT_PRINT("|");
                continue;
            }

            /* Plot Symbol */
            error = *(eyeRawData + phaseIdx * arrayShift + voltageIdx);
            if (0 == error)
            {
                CTC_DKIT_PRINT(".");
            }
            else if ((error > 0) && (threshold1 > error))
            {
                CTC_DKIT_PRINT("*");
            }
            else if ((error > 0) && (threshold2 > error))
            {
                CTC_DKIT_PRINT("+");
            }
            else
            {
                CTC_DKIT_PRINT("#");
            }
        }
        CTC_DKIT_PRINT("\n");
    }

    return CLI_SUCCESS;
}

int32 
_ctc_at_dkit_eom_plot_eye_data(ctc_at_dkit_serdes_dev_t* p_dev, uint32 voltageStepSize, uint32 phaseStepSize, uint32 min_samples, uint32 min_samples_sub,
                                          uint32 berThreshold_sub, uint32 berThreshold, void* p_eye_data)
{
    if(!p_eye_data)
    {
        return CLI_EOL;
    }

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _dkit_at_serdes_56g_eom_data_t* p_eom_data = (_dkit_at_serdes_56g_eom_data_t*) p_eye_data;
        _ctc_at_dkit_plot_eye_data(p_eom_data->eyeRawData[0], p_eom_data->leftEdge, p_eom_data->rightEdge, DKIT_AT56G_EYE_MAX_PHASE_LEVEL / 2, phaseStepSize,
                p_eom_data->upperEdge, p_eom_data->lowerEdge, DKIT_AT56G_EYE_MAX_VOLT_STEPS - 1, voltageStepSize, p_eom_data->sampleCount, (DKIT_AT56G_EYE_MAX_VOLT_STEPS * 2) - 1,
                min_samples, min_samples_sub, berThreshold, berThreshold_sub, p_eom_data->mv_table, 100);
              
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        /* 112g current dont have x axis dimension*/
        uint32 *mVTable = NULL;
        _dkit_at_serdes_112g_eom_data_t* p_eom_data = (_dkit_at_serdes_112g_eom_data_t*) p_eye_data;
        _ctc_at_dkit_plot_eye_data(p_eom_data->eyeRawData[0], p_eom_data->leftEdge, p_eom_data->rightEdge, DKIT_AT112G_EYE_MAX_PHASE_LEVEL / 2, phaseStepSize,
                p_eom_data->upperEdge, p_eom_data->lowerEdge, DKIT_AT112G_EYE_PAM2_VOLT_STEPS - 1, voltageStepSize, p_eom_data->sampleCount, (DKIT_AT112G_EYE_PAM2_VOLT_STEPS * 2) + 1,
                min_samples, min_samples_sub, berThreshold, berThreshold_sub, mVTable, 100);
    }
    
    return CLI_SUCCESS;
}

static void _ctc_at_dkit_display_entry_pam2(     uint32 data, _dkit_at_serdes_56g_tlog_t* entry)
{
    uint32 rawValue;
    char msg[82];
    char* leftString;
    char* rightString;

    entry->isPAM4 = 0;

    /* REMOTE REQUEST PRESET */
    rawValue = data >> 31;
    entry->pam2.remoteReqPreset = (uint8)rawValue;
    leftString = (1 == rawValue) ? DKIT_AT56G_STRING_PRESET_COE : DKIT_AT56G_STRING_NORMAL_OP;
    
    sal_sprintf(msg, "    REMOTE_REQ_PRESET       %s\n", leftString);
    CTC_DKIT_PRINT(msg);

    /* REMOTE REQUEST CTRL_G1 */
    rawValue = (data >> 28) & 0x3;
    entry->pam2.remoteReqCtrlG1 = (uint8)rawValue;
    leftString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_HOLD : DKIT_AT56G_STRING_INC) : (2 == rawValue ? DKIT_AT56G_STRING_DEC : DKIT_AT56G_STRING_DASH);

    /* REMOTE REQUEST STS_G1 */
    rawValue = (data >> 20) & 0x3;
    entry->pam2.remoteReqStsG1 = (uint8)rawValue;
    rightString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_NO_UPDATE : DKIT_AT56G_STRING_UPDATED) : (2 == rawValue ? DKIT_AT56G_STRING_MIN : DKIT_AT56G_STRING_MAX);

    sal_sprintf(msg, "    REMOTE_REQ_CTRL_G1      %-16sREMOTE_REQ_STS_G1       %s\n", leftString, rightString);
    CTC_DKIT_PRINT(msg);

    /* REMOTE REQUEST CTRL_G0 */
    rawValue = (data >> 26) & 0x3;
    entry->pam2.remoteReqCtrlG0 = (uint8)rawValue;
    leftString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_HOLD : DKIT_AT56G_STRING_INC) : (2 == rawValue ? DKIT_AT56G_STRING_DEC : DKIT_AT56G_STRING_DASH);

    /* REMOTE REQUEST STS_G0 */
    rawValue = (data >> 18) & 0x3;
    entry->pam2.remoteReqStsG0 = (uint8)rawValue;
    rightString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_NO_UPDATE : DKIT_AT56G_STRING_UPDATED) : (2 == rawValue ? DKIT_AT56G_STRING_MIN : DKIT_AT56G_STRING_MAX);

    sal_sprintf(msg, "    REMOTE_REQ_CTRL_G0      %-16sREMOTE_REQ_STS_G0       %s\n", leftString, rightString);
    CTC_DKIT_PRINT(msg);

    /* REMOTE REQUEST CTRL_GN1 */
    rawValue = (data >> 24) & 0x3;
    entry->pam2.remoteReqCtrlGN1 = (uint8)rawValue;
    leftString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_HOLD : DKIT_AT56G_STRING_INC) : (2 == rawValue ? DKIT_AT56G_STRING_DEC : DKIT_AT56G_STRING_DASH);

    /* REMOTE REQUEST STS_GN1 */
    rawValue = (data >> 16) & 0x3;
    entry->pam2.remoteReqStsGN1 = (uint8)rawValue;
    rightString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_NO_UPDATE : DKIT_AT56G_STRING_UPDATED) : (2 == rawValue ? DKIT_AT56G_STRING_MIN : DKIT_AT56G_STRING_MAX);

    sal_sprintf(msg, "    REMOTE_REQ_CTRL_GN1     %-16sREMOTE_REQ_STS_GN1      %s\n", leftString, rightString);
    CTC_DKIT_PRINT(msg);

    /* INITIALIZE */
    rawValue = (data >> 30) & 0x1;
    entry->pam2.initialize = (uint8)rawValue;
    leftString = (1 == rawValue) ? DKIT_AT56G_STRING_INIT_COE : DKIT_AT56G_STRING_NORMAL_OP;

    /* READY */
    rawValue = (data >> 23) & 0x1;
    entry->pam2.ready = (uint8)rawValue;
    rightString = (1 == rawValue) ? DKIT_AT56G_STRING_TRUE : DKIT_AT56G_STRING_FALSE;

    sal_sprintf(msg, "    INITIALIZE              %-16sREADY                   %s\n", leftString, rightString);
    CTC_DKIT_PRINT(msg);

    /* LOCAL REQUEST PRESET */
    rawValue = (data >> 13) & 0x3;
    entry->pam2.localReqPreset = (rawValue > DKIT_AT56G_TLOG2_PRESET1) ? DKIT_AT56G_TLOG2_PRESET_NA : (_dkit_at_serdes_56g_tlog2_preset_e)rawValue;
    leftString = (rawValue > DKIT_AT56G_TLOG2_PRESET1) ? DKIT_AT56G_STRING_DASH : (0 == rawValue ? DKIT_AT56G_STRING_PRESET0 : DKIT_AT56G_STRING_PRESET1);

    sal_sprintf(msg, "    LOCAL_REQ_PRESET        %s\n", leftString);
    CTC_DKIT_PRINT(msg);

    /* LOCAL REQUEST CTRL_G1 */
    rawValue = (data >> 11) & 0x3;
    entry->pam2.localReqCtrlG1 = (_dkit_at_serdes_56g_tlog2_ctrl_e)rawValue;
    leftString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_HOLD : DKIT_AT56G_STRING_INC) : (2 == rawValue ? DKIT_AT56G_STRING_DEC : DKIT_AT56G_STRING_DASH);

    /* LOCAL REQUEST STS_G1 */
    rawValue = (data >> 4) & 0x3;
    entry->pam2.localReqStsG1 = (_dkit_at_serdes_56g_tlog2_status_e)rawValue;
    rightString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_NO_UPDATE : DKIT_AT56G_STRING_UPDATED) : (2 == rawValue ? DKIT_AT56G_STRING_MIN : DKIT_AT56G_STRING_MAX);

    sal_sprintf(msg, "    LOCAL_REQ_CTRL_G1       %-16sLOCAL_REQ_STS_G1        %s\n", leftString, rightString);
    CTC_DKIT_PRINT(msg);

    /* LOCAL REQUEST CTRL_G0 */
    rawValue = (data >> 9) & 0x3;
    entry->pam2.localReqCtrlG0 = (_dkit_at_serdes_56g_tlog2_ctrl_e)rawValue;
    leftString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_HOLD : DKIT_AT56G_STRING_INC) : (2 == rawValue ? DKIT_AT56G_STRING_DEC : DKIT_AT56G_STRING_DASH);

    /* LOCAL REQUEST STS_G0 */
    rawValue = (data >> 2) & 0x3;
    entry->pam2.localReqStsG0 = (_dkit_at_serdes_56g_tlog2_status_e)rawValue;
    rightString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_NO_UPDATE : DKIT_AT56G_STRING_UPDATED) : (2 == rawValue ? DKIT_AT56G_STRING_MIN : DKIT_AT56G_STRING_MAX);

    sal_sprintf(msg, "    LOCAL_REQ_CTRL_G0       %-16sLOCAL_REQ_STS_G0        %s\n", leftString, rightString);
    CTC_DKIT_PRINT(msg);

    /* LOCAL REQUEST CTRL_GN1 */
    rawValue = (data >> 6) & 0x3;
    entry->pam2.localReqCtrlGN1 = (_dkit_at_serdes_56g_tlog2_ctrl_e)rawValue;
    leftString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_HOLD : DKIT_AT56G_STRING_INC) : (2 == rawValue ? DKIT_AT56G_STRING_DEC : DKIT_AT56G_STRING_DASH);

    /* LOCAL REQUEST STS_GN1 */
    rawValue = data & 0x3;
    entry->pam2.localReqStsGN1 = (_dkit_at_serdes_56g_tlog2_status_e)rawValue;
    rightString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_NO_UPDATE : DKIT_AT56G_STRING_UPDATED) : (2 == rawValue ? DKIT_AT56G_STRING_MIN : DKIT_AT56G_STRING_MAX);

    sal_sprintf(msg, "    LOCAL_REQ_CTRL_GN1      %-16sLOCAL_REQ_STS_GN1       %s\n", leftString, rightString);
    CTC_DKIT_PRINT(msg);
}

static void _ctc_at_dkit_display_entry_pam4(    uint32 data, _dkit_at_serdes_56g_tlog_t* entry)
{
    uint32 rawValue;
    char msg[82];
    char* leftString;
    char* rightString;

    entry->isPAM4 = 1;

    /* REMOTE REQ CTRL_PAT */
    rawValue = (data >> 27) & 0x3;
    entry->pam4.remoteReqCtrlPat = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_TLOG4_PAT_PAM2 : DKIT_AT56G_TLOG4_PAT_NA) : (2 == rawValue ? DKIT_AT56G_TLOG4_PAT_PAM4 : DKIT_AT56G_TLOG4_PAT_PAM4_PRE);
    leftString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_PAM2 : DKIT_AT56G_STRING_DASH) : (2 == rawValue ? DKIT_AT56G_STRING_PAM4 : DKIT_AT56G_STRING_PAM4_PRE);

    /* REMOTE REQ PRESET */
    rawValue = (data >> 29) & 0x3;
    entry->pam4.remoteReqPreset = (_dkit_at_serdes_56g_tlog4_preset_e)rawValue;
    rightString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_PRESET0 : DKIT_AT56G_STRING_PRESET1) : (2 == rawValue ? DKIT_AT56G_STRING_PRESET2 : DKIT_AT56G_STRING_PRESET3);

    sal_sprintf(msg, "    REMOTE_REQ_CTRL_PATTERN %-16sREMOTE_REQ_PRESET       %s\n", leftString, rightString);
    CTC_DKIT_PRINT(msg);

    /* REMOTE REQ CTRL_G */
    rawValue = (data >> 22) & 0x3;
    entry->pam4.remoteReqCtrlG = (_dkit_at_serdes_56g_tlog4_ctrl_e)rawValue;
    leftString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_HOLD : DKIT_AT56G_STRING_INC) : (2 == rawValue ? DKIT_AT56G_STRING_DEC : DKIT_AT56G_STRING_NO_EQ);

    /* REMOTE REQ STS_G */
    rawValue = (data >> 16) & 0x7;
    entry->pam4.remoteReqStsG = (_dkit_at_serdes_56g_tlog4_ctrl_e)rawValue;
    switch (rawValue)
    {
    case (0):
        entry->pam4.remoteReqStsG = DKIT_AT56G_TLOG4_STS_NO_UPDATE;
        rightString = DKIT_AT56G_STRING_NO_UPDATE;
        break;
    case (1):
        entry->pam4.remoteReqStsG = DKIT_AT56G_TLOG4_STS_UPDATE;
        rightString = DKIT_AT56G_STRING_UPDATED;
        break;
    case (2):
        entry->pam4.remoteReqStsG = DKIT_AT56G_TLOG4_STS_COE_L;
        rightString = DKIT_AT56G_STRING_COE_LIMIT;
        break;
    case (3):
        entry->pam4.remoteReqStsG = DKIT_AT56G_TLOG4_STS_COE_NA;
        rightString = DKIT_AT56G_STRING_COE_NA;
        break;
    case (4):
        entry->pam4.remoteReqStsG = DKIT_AT56G_TLOG4_STS_EQ_L;
        rightString = DKIT_AT56G_STRING_EQ_LIMIT;
        break;
    case (6):
        entry->pam4.remoteReqStsG = DKIT_AT56G_TLOG4_STS_EQ_COE_L;
        rightString = DKIT_AT56G_STRING_EQ_COE_LIMIT;
        break;
    default:
        entry->pam4.remoteReqStsG = DKIT_AT56G_TLOG4_STS_NA;
        rightString = DKIT_AT56G_STRING_DASH;
    }

    sal_sprintf(msg, "    REMOTE_REQ_CTRL_G       %-16sREMOTE_REQ_STS_G        %s\n", leftString, rightString);
    CTC_DKIT_PRINT(msg);

    /* REMOTE REQ CTRL_SEL */
    rawValue = (data >> 24) & 0x7;
    switch (rawValue)
    {
    case (0):
        entry->pam4.remoteReqCtrlSel = DKIT_AT56G_TLOG4_SEL_COE_P0;
        leftString = DKIT_AT56G_STRING_COE0;
        break;
    case (1):
        entry->pam4.remoteReqCtrlSel = DKIT_AT56G_TLOG4_SEL_COE_P1;
        leftString = DKIT_AT56G_STRING_COE1;
        break;
    case (5):
        entry->pam4.remoteReqCtrlSel = DKIT_AT56G_TLOG4_SEL_COE_N3;
        leftString = DKIT_AT56G_STRING_COEN3;
        break;
    case (6):
        entry->pam4.remoteReqCtrlSel = DKIT_AT56G_TLOG4_SEL_COE_N2;
        leftString = DKIT_AT56G_STRING_COEN2;
        break;
    case (7):
        entry->pam4.remoteReqCtrlSel = DKIT_AT56G_TLOG4_SEL_COE_N1;
        leftString = DKIT_AT56G_STRING_COEN1;
        break;
    default:
        entry->pam4.remoteReqCtrlSel = DKIT_AT56G_TLOG4_SEL_NA;
        leftString = DKIT_AT56G_STRING_DASH;
    }

    /* REMOTE REQ READY */
    rawValue = (data >> 19) & 0x1;
    entry->pam4.ready = (uint8)rawValue;
    rightString = (1 == rawValue) ? DKIT_AT56G_STRING_TRUE : DKIT_AT56G_STRING_FALSE;

    sal_sprintf(msg, "    REMOTE_REQ_CTRL_SEL     %-16sREADY                   %s\n", leftString, rightString);
    CTC_DKIT_PRINT(msg);

    /* LOCAL REQ CTRL_PAT */
    rawValue = (data >> 11) & 0x3;
    entry->pam4.localReqCtrlPat = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_TLOG4_PAT_PAM2 : DKIT_AT56G_TLOG4_PAT_NA) : (2 == rawValue ? DKIT_AT56G_TLOG4_PAT_PAM4 : DKIT_AT56G_TLOG4_PAT_PAM4_PRE);
    leftString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_PAM2 : DKIT_AT56G_STRING_DASH) : (2 == rawValue ? DKIT_AT56G_STRING_PAM4 : DKIT_AT56G_STRING_PAM4_PRE);

    /* LOCAL REQ PRESET */
    rawValue = (data >> 13) & 0x3;
    entry->pam4.localReqPreset = (_dkit_at_serdes_56g_tlog4_preset_e)rawValue;
    rightString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_PRESET0 : DKIT_AT56G_STRING_PRESET1) : (2 == rawValue ? DKIT_AT56G_STRING_PRESET2 : DKIT_AT56G_STRING_PRESET3);

    sal_sprintf(msg, "    LOCAL_REQ_CTRL_PATTERN  %-16sLOCAL_REQ_PRESET        %s\n", leftString, rightString);
    CTC_DKIT_PRINT(msg);

    /* LOCAL REQ CTRL_G */
    rawValue = (data >> 6) & 0x3;
    entry->pam4.localReqCtrlG = (_dkit_at_serdes_56g_tlog4_ctrl_e)rawValue;
    leftString = (rawValue < 2) ? (0 == rawValue ? DKIT_AT56G_STRING_HOLD : DKIT_AT56G_STRING_INC) : (2 == rawValue ? DKIT_AT56G_STRING_DEC : DKIT_AT56G_STRING_NO_EQ);

    /* LOCAL REQ STS_G */
    rawValue = data & 0x7;
    entry->pam4.localReqStsG = (_dkit_at_serdes_56g_tlog4_ctrl_e)rawValue;
    switch (rawValue)
    {
        case (0):
            entry->pam4.localReqStsG = DKIT_AT56G_TLOG4_STS_NO_UPDATE;
            rightString = DKIT_AT56G_STRING_NO_UPDATE;
            break;
        case (1):
            entry->pam4.localReqStsG = DKIT_AT56G_TLOG4_STS_UPDATE;
            rightString = DKIT_AT56G_STRING_UPDATED;
            break;
        case (2):
            entry->pam4.localReqStsG = DKIT_AT56G_TLOG4_STS_COE_L;
            rightString = DKIT_AT56G_STRING_COE_LIMIT;
            break;
        case (3):
            entry->pam4.localReqStsG = DKIT_AT56G_TLOG4_STS_COE_NA;
            rightString = DKIT_AT56G_STRING_COE_NA;
            break;
        case (4):
            entry->pam4.localReqStsG = DKIT_AT56G_TLOG4_STS_EQ_L;
            rightString = DKIT_AT56G_STRING_EQ_LIMIT;
            break;
        case (6):
            entry->pam4.localReqStsG = DKIT_AT56G_TLOG4_STS_EQ_COE_L;
            rightString = DKIT_AT56G_STRING_EQ_COE_LIMIT;
            break;
        default:
            entry->pam4.localReqStsG = DKIT_AT56G_TLOG4_STS_NA;
            rightString = DKIT_AT56G_STRING_DASH;
            break;
    }

    sal_sprintf(msg, "    LOCAL_REQ_CTRL_G        %-16sLOCAL_REQ_STS_G         %s\n", leftString, rightString);
    CTC_DKIT_PRINT(msg);

    /* LOCAL REQ CTRL_SEL */
    rawValue = (data >> 8) & 0x7;
    switch (rawValue)
    {
        case (0):
            entry->pam4.localReqCtrlSel = DKIT_AT56G_TLOG4_SEL_COE_P0;
            leftString = DKIT_AT56G_STRING_COE0;
            break;
        case (1):
            entry->pam4.localReqCtrlSel = DKIT_AT56G_TLOG4_SEL_COE_P1;
            leftString = DKIT_AT56G_STRING_COE1;
            break;
        case (5):
            entry->pam4.localReqCtrlSel = DKIT_AT56G_TLOG4_SEL_COE_N3;
            leftString = DKIT_AT56G_STRING_COEN3;
            break;
        case (6):
            entry->pam4.localReqCtrlSel = DKIT_AT56G_TLOG4_SEL_COE_N2;
            leftString = DKIT_AT56G_STRING_COEN2;
            break;
        case (7):
            entry->pam4.localReqCtrlSel = DKIT_AT56G_TLOG4_SEL_COE_N1;
            leftString = DKIT_AT56G_STRING_COEN1;
            break;
        default:
            entry->pam4.localReqCtrlSel = DKIT_AT56G_TLOG4_SEL_NA;
            leftString = DKIT_AT56G_STRING_DASH;
            break;
    }

    /* LOCAL REQ STS_ACK */
    rawValue = (data >> 3) & 0x1;
    entry->pam4.stsAck = (uint8)rawValue;
    rightString = (1 == rawValue) ? DKIT_AT56G_STRING_TRUE : DKIT_AT56G_STRING_FALSE;

    sal_sprintf(msg, "    LOCAL_REQ_CTRL_SEL      %-16sSTS_ACK                 %s\n", leftString, rightString);
    CTC_DKIT_PRINT(msg);
}

void
_ctc_at_dkit_display_training_log(ctc_at_dkit_serdes_dev_t* p_dev, sal_file_t p_file, void* p_training_log, uint32 entry_size, uint32* valid_entries)
{
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _dkit_at_serdes_56g_tlog_t* p_56g_training_log = (_dkit_at_serdes_56g_tlog_t*)p_training_log;
        _dkit_at_serdes_56g_tlog_t entry;
        uint32 data, baseAddr, addrOffset;
        uint16 logCount, iterLog;
        uint8 index = 0;
        uint8 isPAM4, bufferFull;
        uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);

        sal_memset((void*)&entry, 0xff, sizeof(_dkit_at_serdes_56g_tlog_t));
        
        CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_file, " Display Training Log (lane=%d)\n", lane);
    
        baseAddr = 0x6A00;
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(DKIT_AT_SERDES_FLD_DEF(baseAddr, 7, 0)) /* counter */, CTC_AT_DKIT_SERDES_REG_LANE, &data);
        logCount = (uint16)data;
        if (0 == logCount)
        {
            CTC_DKITS_PRINT_FILE(p_file, " No entries in log\n");
        }
    
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(DKIT_AT_SERDES_FLD_DEF(baseAddr, 8, 8)) /* log type */, CTC_AT_DKIT_SERDES_REG_LANE, &data);
        isPAM4 = (uint8)data;
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(DKIT_AT_SERDES_FLD_DEF(baseAddr, 9, 9)) /* full indicator */, CTC_AT_DKIT_SERDES_REG_LANE, &data);
        bufferFull = (uint8)data;
    
        for (iterLog = logCount + 63 * bufferFull; iterLog > (bufferFull ? logCount : 0); iterLog--)
        {
            /* Calculates entry's address offset from base address */
            addrOffset = ((iterLog - 1) % 63) + 1;
    
            _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(DKIT_AT_SERDES_FLD_DEF(baseAddr + 0x4 * addrOffset, 31, 0)), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    
            if (isPAM4)
            {
               CTC_DKITS_PRINT_FILE(p_file, " ----> Entry %u (PAM4)\n", iterLog);
               _ctc_at_dkit_display_entry_pam4(data, &entry);
            }
            else
            {
               CTC_DKITS_PRINT_FILE(p_file, " ----> Entry %u (PAM2)\n", iterLog);
               _ctc_at_dkit_display_entry_pam2(data, &entry);
            }
    
            if ((p_56g_training_log != NULL) && (index < entry_size))
                p_56g_training_log[index++] = entry;
        }

        if(valid_entries != NULL)
        {
            *valid_entries = index;
        }
        

    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        /*112g current not support */
    }
}

uint8
_ctc_at_dkit_get_serdes_modulation_mode(ctc_at_dkit_serdes_dev_t* p_dev)
{
    uint32 value = DKIT_AT_USELESS_ID32;

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_read_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_PAM2_EN), CTC_AT_DKIT_SERDES_REG_LANE, &value);
        value = (value == 1) ? CTC_DKIT_AT_SERDES_NRZ_MODE : CTC_DKIT_AT_SERDES_PAM4_MODE;
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        /* 112G IP don't have pam2en register , need confirm  */
        value = DKIT_AT_USELESS_ID32;
    }

    return (uint8)value;
}

void _ctc_at_dkit_serdes_dev(uint8 lchip, uint16 serdes_id, ctc_at_dkit_serdes_dev_t* p_dev)
{
    p_dev->lchip = lchip;
    p_dev->serdes_id = serdes_id;
    p_dev->type = _ctc_at_dkit_get_serdes_type(lchip, serdes_id);
}

#define __PRBS__

/********************************************************
 *AT SerDes PRBS Mode
 *  0x09  : PRBS1T
 *  0x0a  : PRBS2T
 *  0x0b  : PRBS4T
 *  0x0c  : PRBS5T(40bit only)
 *  0x0d  : PRBS8T(32bit only)
 *  0x0e  : PRBS10T(40bit only)
 *  0x10  : PRBS 7   
 *  0x11  : PRBS 9
 *  0x12  : PRBS 11
 *  0x17  : PRBS 15
 *  0x18  : PRBS 16
 *  0x19  : PRBS 23
 *  0x1a  : PRBS 31
 *  0x1b  : PRBS 32
 */

#if 0
STATIC uint8
_ctc_at_dkit_misc_serdes_prbs_pattern_convert(uint8 cli_pattern)
{
    uint8 pattern = 0;

    switch(cli_pattern)
    {
        /*PRBS7+ & PRBS7-*/
        case 0:
        case 1:
            pattern = 0x10;/*PRBS7*/
            break;
        /*PRBS15+ & PRBS15-*/
        case 2:
        case 3:
            pattern = 0x17;/*PRBS15*/
            break;
        /*PRBS23+ & PRBS23-*/    
        case 4:
        case 5:
            pattern = 0x19;/*PRBS23*/
            break;
        /*PRBS31+ & PRBS31-*/
        case 6:
        case 7:
            pattern = 0x1a;/*PRBS31*/
            break;
        /*PRBS9*/
        case 8:
            pattern = 0x11;/*PRBS9*/
            break;
        /*PRBS9*/
        case 10:
            pattern = 0x12;/*PRBS11*/
            break;
        case 11:
            pattern = 0x09;/*PRBS1T(1010)*/
            break;
        default:
            return CLI_ERROR;
    }
    
    return pattern;
}
#endif

int32
_ctc_at_dkit_misc_serdes_prbs_en(uint8 lchip, ctc_dkit_at_serdes_ctl_prbs_t *p_prbs)
{
    ctc_at_dkit_serdes_dev_t dev;
    uint8  enable;
    uint32 prbs_en;
    
    enable = (CTC_DKIT_SERDIS_CTL_ENABLE == p_prbs->oper ? TRUE : FALSE);

    _ctc_at_dkit_serdes_dev(lchip, p_prbs->serdes_id, &dev);

    _ctc_at_dkit_get_prbs_en(&dev, DKIT_AT_DIR_TX, &prbs_en);  
    
    /* prbs or test pattern is already enable, do not need operation */
    if(enable && prbs_en)
    {
        CTC_DKIT_PRINT("prbs is enable, need disable first.\n");    
        return CLI_EOL;
    }

    _ctc_at_dkit_set_prbs_pattern(&dev, DKIT_AT_DIR_TX, p_prbs->pattern);
    _ctc_at_dkit_set_prbs_en(&dev, DKIT_AT_DIR_TX, enable);
    _ctc_at_dkit_set_tx_en(&dev, 1);

    return CLI_SUCCESS;
}


/* prbs rx check */
void
_ctc_at_dkit_misc_serdes_ber_record_start(uint8 lchip, uint16 serdes_id)
{
    ctc_dkit_at_serdes_ber_mon_t* p_ber_mon = 
        (ctc_dkit_at_serdes_ber_mon_t*)g_usw_dkit_master[lchip]->monitor_task[CTC_DKIT_MONITOR_TASK_PRBS_BER].para;
    if(0 == p_ber_mon->is_mon[serdes_id])
    {
        p_ber_mon->is_mon[serdes_id] = 1;
        p_ber_mon->tot_cnt[serdes_id] = 0;
        p_ber_mon->err_cnt[serdes_id] = 0;
        p_ber_mon->is_run = 1;
    }
}

void
_ctc_at_dkit_misc_serdes_ber_record_clear(uint8 lchip, uint16 serdes_id)
{
    uint16 i;
    uint8  is_run = 0;
    ctc_dkit_at_serdes_ber_mon_t* p_ber_mon = 
        (ctc_dkit_at_serdes_ber_mon_t*)g_usw_dkit_master[lchip]->monitor_task[CTC_DKIT_MONITOR_TASK_PRBS_BER].para;
    if(!p_ber_mon) return;
    
    p_ber_mon->is_mon[serdes_id] = 0;
    p_ber_mon->tot_cnt[serdes_id] = 0;
    p_ber_mon->err_cnt[serdes_id] = 0;

    for(i = 0; i < DKIT_SERDES_ID_MAX; i++)
    {
        if(p_ber_mon->is_mon[i])
        {
            is_run = 1;
            break;
        }
    }
    p_ber_mon->is_run = is_run;
}

int32 _ctc_at_dkit_misc_serdes_opr_lock(uint8 lchip, uint16 serdes_id)
{
    ctc_dkit_monitor_task_t* p_mon_task = &(g_usw_dkit_master[lchip]->monitor_task[CTC_DKIT_MONITOR_TASK_PRBS_BER]);
    ctc_dkit_at_serdes_ber_mon_t* p_ber_mon = NULL;
    uint16 try_time = 3000;

    if(!p_mon_task) return CLI_SUCCESS;

    p_ber_mon = (ctc_dkit_at_serdes_ber_mon_t*)p_mon_task->para;
    
    if(!p_ber_mon) return CLI_SUCCESS;

    while(try_time--)
    {
        if(p_ber_mon->opr_lock[serdes_id])
        {
            sal_task_sleep(1);
        }
        else
        {
            p_ber_mon->opr_lock[serdes_id] = 1;
            return CLI_SUCCESS;
        }
    }
    return CLI_ERROR;
}

int32 _ctc_at_dkit_misc_serdes_opr_unlock(uint8 lchip, uint16 serdes_id)
{
    ctc_dkit_monitor_task_t* p_mon_task = &(g_usw_dkit_master[lchip]->monitor_task[CTC_DKIT_MONITOR_TASK_PRBS_BER]);
    ctc_dkit_at_serdes_ber_mon_t* p_ber_mon = NULL;

    if(!p_mon_task) return CLI_SUCCESS;

    p_ber_mon = (ctc_dkit_at_serdes_ber_mon_t*)p_mon_task->para;
    
    if(!p_ber_mon) return CLI_SUCCESS;

    p_ber_mon->opr_lock[serdes_id] = 0;
    return CLI_SUCCESS;
}

STATIC void
_ctc_at_dkit_misc_serdes_monitor_prbs_stat_handler(void* arg)
{
    ctc_dkit_at_serdes_ber_mon_t* p_ber_mon = (ctc_dkit_at_serdes_ber_mon_t*)arg;
    ctc_at_dkit_serdes_dev_t dev;
    _dkit_at_serdes_pattern_stats_t prbs_stats;
    uint8  lchip = p_ber_mon->lchip;
    uint16 serdes_id = 0;

    while(1)
    {
        if(g_usw_dkit_master[lchip]->monitor_task[CTC_DKIT_MONITOR_TASK_PRBS_BER].task_end)
        {
            return;
        }

        for(serdes_id = 0; serdes_id < DKIT_SERDES_ID_MAX; serdes_id++)
        {
            if(!p_ber_mon->is_mon[serdes_id]) continue;
            if(!p_ber_mon->is_run) return;
            
            _ctc_at_dkit_serdes_dev(lchip, serdes_id, &dev);

            _ctc_at_dkit_misc_serdes_opr_lock(lchip, serdes_id);

            _ctc_at_dkit_get_comparator_stats(&dev, &prbs_stats);
            _ctc_at_dkit_reset_comparator_stats(&dev);
            p_ber_mon->err_cnt[serdes_id] += prbs_stats.totalErrorBits;
            p_ber_mon->tot_cnt[serdes_id] += prbs_stats.totalBits;

            _ctc_at_dkit_misc_serdes_opr_unlock(lchip, serdes_id);

            sal_task_sleep(1);
        }
            
        sal_task_sleep(1000);
    }
}

void
_ctc_at_dkit_misc_serdes_get_rx_train_stat(ctc_at_dkit_serdes_dev_t* p_dev, uint16* p_en, uint16* p_co, uint16* p_fa)
{
    uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
       switch (lane)
       {
        case 0:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN0, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINCO0, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINFA0, p_fa);
            break;
        case 1:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN1, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINCO1, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINFA1, p_fa);
            break;
        case 2:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN2, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINCO2, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINFA2, p_fa);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN3, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINCO3, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINFA3, p_fa);
            break;
       }  
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
       switch (lane)
       {
        case 0:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN0, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_CO0, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_FA0, p_fa);
            break;
        case 1:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN1, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_CO1, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_FA1, p_fa);
            break;
        case 2:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN2, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_CO2, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_FA2, p_fa);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN3, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_CO3, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_FA3, p_fa);
            break;
       }  
    }
}

void
_ctc_at_dkit_misc_serdes_get_tx_train_stat(ctc_at_dkit_serdes_dev_t* p_dev, uint16* p_en, uint16* p_co, uint16* p_fa)
{
    uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
       switch (lane)
       {
        case 0:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_TRAINEN0, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_TRAINCO0, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_TRAINFA0, p_fa);
            break;
        case 1:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_TRAINEN1, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_TRAINCO1, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_TRAINFA1, p_fa);
            break;
        case 2:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_TRAINEN2, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_TRAINCO2, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_TRAINFA2, p_fa);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_TRAINEN3, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_TRAINCO3, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT56G_PIN_TX_TRAINFA3, p_fa);
            break;
       }  
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
       switch (lane)
       {
        case 0:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_TRAIN_EN0, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_TRAIN_CO0, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_TRAIN_FA0, p_fa);
            break;
        case 1:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_TRAIN_EN1, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_TRAIN_CO1, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_TRAIN_FA1, p_fa);
            break;
        case 2:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_TRAIN_EN2, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_TRAIN_CO2, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_TRAIN_FA2, p_fa);
            break;
        case 3:
        default:
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_TRAIN_EN3, p_en);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_TRAIN_CO3, p_co);
            _ctc_at_dkit_serdes_get_pin(p_dev, DKIT_AT112G_PIN_TX_TRAIN_FA3, p_fa);
            break;
       }  
    }
}

int32
_ctc_at_dkit_misc_serdes_prbs_check(uint8 lchip, ctc_dkit_at_serdes_ctl_prbs_t *p_prbs)
{
    uint32 cur_en;
    uint32 pattern;
    uint32 ret;
    uint8  is_keep   = p_prbs->is_keep;
    uint16 serdes_id = p_prbs->serdes_id;
    uint32 delay     = p_prbs->timer_ms;
    uint16 en = 0;
    uint16 co = 0;
    uint16 fa = 0;
    uint32 gap_ms = 100;
    uint32 times = 30;
    ctc_at_dkit_serdes_dev_t dev;
    ctc_dkit_monitor_task_t* p_mon_task = &(g_usw_dkit_master[lchip]->monitor_task[CTC_DKIT_MONITOR_TASK_PRBS_BER]);
    _dkit_at_serdes_pattern_stats_t prbs_stats;
    ctc_dkit_at_serdes_ber_mon_t* p_ber_mon = NULL;
    char thread_name[SAL_TASK_MAX_NAME_LEN] = {0};

    _ctc_at_dkit_serdes_dev(lchip, serdes_id, &dev);

    _ctc_at_dkit_misc_serdes_opr_lock(lchip, serdes_id);

    /* 1. set rx prbs pattern & enable stats*/
    _ctc_at_dkit_get_prbs_pattern(&dev, DKIT_AT_DIR_RX, &pattern);
    if(pattern != p_prbs->pattern)
    {
        _ctc_at_dkit_set_prbs_pattern(&dev, DKIT_AT_DIR_RX, p_prbs->pattern);
    }
    _ctc_at_dkit_get_prbs_en(&dev, DKIT_AT_DIR_RX, &cur_en);
    if(!cur_en)
    {
        _ctc_at_dkit_set_prbs_en(&dev, DKIT_AT_DIR_RX, 1);
        /*wait previous tx || rx train done*/
        while(times--)
        {
            _ctc_at_dkit_misc_serdes_get_rx_train_stat(&dev, &en, &co, &fa);
            if((!en) || (en && co))
            {
                break;
            }
            sal_task_sleep(gap_ms);
        }
        times = 30;
        while(times--)
        {
            _ctc_at_dkit_misc_serdes_get_tx_train_stat(&dev, &en, &co, &fa);
            if((!en) || (en && co))
            {
                break;
            }
            sal_task_sleep(gap_ms);
        }
        _ctc_at_dkit_reset_comparator_stats(&dev);
    }

    /* 2. ber monitor operation: if current is not keep, clear stats and destroy thread; else enable monitor */
    if(!is_keep)
    {
        _ctc_at_dkit_misc_serdes_ber_record_clear(lchip, serdes_id);

        if(p_mon_task->monitor_task)
        {
            p_ber_mon = (ctc_dkit_at_serdes_ber_mon_t*)p_mon_task->para;
            if(p_ber_mon && (0 == p_ber_mon->is_run))
            {
                p_mon_task->task_end = 1;
                sal_task_destroy(p_mon_task->monitor_task);
                p_mon_task->monitor_task = NULL;
                if(p_mon_task->para)
                {
                    mem_free(p_mon_task->para);
                    p_mon_task->para = NULL;
                }
            }
        }
    }
    else
    {
        if(NULL == p_mon_task->monitor_task)
        {
            if(NULL == p_mon_task->para)
            {
                p_ber_mon = (ctc_dkit_at_serdes_ber_mon_t*)mem_malloc(MEM_CLI_MODULE, 
                    sizeof(ctc_dkit_at_serdes_ber_mon_t));
                if(NULL == p_ber_mon)
                {
                    return CLI_ERROR;
                }
                sal_memset(p_ber_mon, 0, sizeof(ctc_dkit_at_serdes_ber_mon_t));
                p_ber_mon->lchip = lchip;
                sal_memset(p_ber_mon->opr_lock, 0, sizeof(uint8)*DKIT_SERDES_ID_MAX);
                sal_memset(p_ber_mon->is_mon, 0, sizeof(uint8)*DKIT_SERDES_ID_MAX);
                sal_memset(p_ber_mon->tot_cnt, 0, sizeof(uint64)*DKIT_SERDES_ID_MAX);
                sal_memset(p_ber_mon->err_cnt, 0, sizeof(uint64)*DKIT_SERDES_ID_MAX);
                p_mon_task->para = (void*)p_ber_mon;
            }
            p_mon_task->task_end = 0;
            sal_sprintf(thread_name, "AT-Serdes-PRBS-BER-MON-%d", lchip);
            ret = sal_task_create(&p_mon_task->monitor_task,
                                thread_name,
                                SAL_DEF_TASK_STACK_SIZE,
                                SAL_TASK_PRIO_DEF,
                                _ctc_at_dkit_misc_serdes_monitor_prbs_stat_handler,
                                p_mon_task->para);
            if(CLI_ERROR == ret)
            {
                return CLI_ERROR;
            }
        }
        _ctc_at_dkit_misc_serdes_ber_record_start(lchip, serdes_id);
    }

    /* 3. wait proper time to accumulate count */
    if(is_keep)
    {
        delay = 0;
    }
    else
    {
        if(0 == delay)
        {
            delay = 1000;
        }
    }
    sal_task_sleep(delay); 
    /*_ctc_at_dkit_misc_serdes_get_rx_train_stat(&dev, &en, &co, &fa);*/
    /*printf("en %u, co %u, fa %u\n", en, co, fa);*/

    /* 4. get current count */
    _ctc_at_dkit_get_comparator_stats(&dev, &prbs_stats);
    _ctc_at_dkit_reset_comparator_stats(&dev);

    if(is_keep)
    {
        p_ber_mon = (ctc_dkit_at_serdes_ber_mon_t*)p_mon_task->para;
        p_ber_mon->err_cnt[serdes_id] += prbs_stats.totalErrorBits;
        p_ber_mon->tot_cnt[serdes_id] += prbs_stats.totalBits;
        p_prbs->errcnt = p_ber_mon->err_cnt[serdes_id];
        p_prbs->totcnt = p_ber_mon->tot_cnt[serdes_id];
    }
    else
    {
        p_prbs->errcnt = prbs_stats.totalErrorBits;
        p_prbs->totcnt = prbs_stats.totalBits;
    }

    /* 5. disable rx prbs pattern */
    if(!is_keep)
    {
        _ctc_at_dkit_set_prbs_en(&dev, DKIT_AT_DIR_RX, 0);
    }

    _ctc_at_dkit_misc_serdes_opr_unlock(lchip, serdes_id);

    return CLI_SUCCESS;
}



STATIC int32
_ctc_at_dkit_misc_do_serdes_prbs(uint8 lchip, ctc_dkit_at_serdes_ctl_prbs_t *p_prbs)
{
    int32 ret = CLI_SUCCESS;

    switch(p_prbs->oper)
    {
        case CTC_DKIT_SERDIS_CTL_ENABLE:
        case CTC_DKIT_SERDIS_CTL_DISABLE:
            ret = _ctc_at_dkit_misc_serdes_prbs_en(lchip, p_prbs);
            break;
        case CTC_DKIT_SERDIS_CTL_CHECK:
            ret = _ctc_at_dkit_misc_serdes_prbs_check(lchip, p_prbs);
            break;
        default:
            CTC_DKIT_PRINT("Feature not supported!\n");
            break;
    }
    return ret;
}

uint8 _ctc_at_dkit_serdes_get_related_serdes_speed(uint8 txrx_speed, uint8 type)
{
    uint8 serdes_speed = 0;
    if(CTC_AT_DKIT_SERDES_56G == type)
    {
        switch(txrx_speed)
        {
            case DKIT_AT56G_SERDES_1P25G   :
                serdes_speed = DKIT_SERDES_SPEED_1_25G;
                break;
            case DKIT_AT56G_SERDES_3P125G  :
                serdes_speed = DKIT_SERDES_SPEED_3_125G;
                break;
            case DKIT_AT56G_SERDES_10P3125G:
                serdes_speed = DKIT_SERDES_SPEED_10_3125G;
                break;
            case DKIT_AT56G_SERDES_12P5G   :
                serdes_speed = DKIT_SERDES_SPEED_12_5G;
                break;
            case DKIT_AT56G_SERDES_25P7812G:
                serdes_speed = DKIT_SERDES_SPEED_25_78125G;
                break;
            case DKIT_AT56G_SERDES_26P5625G:
                serdes_speed = DKIT_SERDES_SPEED_26_5625G;
                break;
            case DKIT_AT56G_SERDES_28P125G :
                serdes_speed = DKIT_SERDES_SPEED_28_125G;
                break;
            case DKIT_AT56G_SERDES_51P5625G:
                serdes_speed = DKIT_SERDES_SPEED_51_5625G;
                break;
            case DKIT_AT56G_SERDES_53P125G :
                serdes_speed = DKIT_SERDES_SPEED_53_125G;
                break;
            case DKIT_AT56G_SERDES_56P25G  :
                serdes_speed = DKIT_SERDES_SPEED_56_25G;
                break;
            case DKIT_AT56G_SERDES_10P9375G:
                serdes_speed = DKIT_SERDES_SPEED_10_9375G;
                break;
            case DKIT_AT56G_SERDES_12P96875G:
                serdes_speed = DKIT_SERDES_SPEED_12_96875G;
                break;
            case DKIT_AT56G_SERDES_27P34375G:
                serdes_speed = DKIT_SERDES_SPEED_27_34375G;
                break;
            case DKIT_AT56G_SERDES_27P78125G:
                serdes_speed = DKIT_SERDES_SPEED_27_78125G;
                break;
            case DKIT_AT56G_SERDES_20P625G :
                serdes_speed = DKIT_SERDES_SPEED_20_625G;
                break;
            case DKIT_AT56G_SERDES_11P40625G:
                serdes_speed = DKIT_SERDES_SPEED_11_40625G;
                break;
            case DKIT_AT56G_SERDES_1P0625G :
            case DKIT_AT56G_SERDES_1P2288G :
            case DKIT_AT56G_SERDES_2P02752G:
            case DKIT_AT56G_SERDES_2P125G  :
            case DKIT_AT56G_SERDES_2P4576G :
            case DKIT_AT56G_SERDES_2P5G    :
            case DKIT_AT56G_SERDES_2P57812G:
            case DKIT_AT56G_SERDES_4P08804G:
            case DKIT_AT56G_SERDES_4P25G   :
            case DKIT_AT56G_SERDES_4P9152G :
            case DKIT_AT56G_SERDES_5G      :
            case DKIT_AT56G_SERDES_5P15625G:
            case DKIT_AT56G_SERDES_6P144G  :
            case DKIT_AT56G_SERDES_6P25G   :
            case DKIT_AT56G_SERDES_7P3728G :
            case DKIT_AT56G_SERDES_7P5G    :
            case DKIT_AT56G_SERDES_8P11008G:
            case DKIT_AT56G_SERDES_8P5G    :
            case DKIT_AT56G_SERDES_9P8304G :
            case DKIT_AT56G_SERDES_10G     :
            case DKIT_AT56G_SERDES_10P137G :
            case DKIT_AT56G_SERDES_10P5187G:
            case DKIT_AT56G_SERDES_12P1651G:
            case DKIT_AT56G_SERDES_12P1875G:
            case DKIT_AT56G_SERDES_12P8906G:
            case DKIT_AT56G_SERDES_14P025G :
            case DKIT_AT56G_SERDES_14P7456G:
            case DKIT_AT56G_SERDES_15G     :
            case DKIT_AT56G_SERDES_16P2201G:
            case DKIT_AT56G_SERDES_24P3302G:
            case DKIT_AT56G_SERDES_275G    :
            case DKIT_AT56G_SERDES_28P05G  :
            case DKIT_AT56G_SERDES_32G     :
            case DKIT_AT56G_SERDES_46P25G  :
            case DKIT_AT56G_SERDES_56G     :
            case DKIT_AT56G_SERDES_56P1G   :
            case DKIT_AT56G_SERDES_64G     :
            case DKIT_AT56G_SERDES_3P072G  :
            case DKIT_AT56G_SERDES_12P288G :
            case DKIT_AT56G_SERDES_19P6608G:
            case DKIT_AT56G_SERDES_MAX_G   :
            default:
                serdes_speed = DKIT_SERDES_SPEED_0G;
                break;
        }
    }
    else
    {
        switch(txrx_speed)
        {
            case DKIT_AT112G_SERDES_1P25G    :
                serdes_speed = DKIT_SERDES_SPEED_1_25G;
                break;
            case DKIT_AT112G_SERDES_3P125G   :
                serdes_speed = DKIT_SERDES_SPEED_3_125G;
                break;
            case DKIT_AT112G_SERDES_10P3125G :
                serdes_speed = DKIT_SERDES_SPEED_10_3125G;
                break;
            case DKIT_AT112G_SERDES_12P5G    :
                serdes_speed = DKIT_SERDES_SPEED_12_5G;
                break;
            case DKIT_AT112G_SERDES_25P78125G:
                serdes_speed = DKIT_SERDES_SPEED_25_78125G;
                break;
            case DKIT_AT112G_SERDES_26P5625G :
                serdes_speed = DKIT_SERDES_SPEED_26_5625G;
                break;
            case DKIT_AT112G_SERDES_28P125G  :
                serdes_speed = DKIT_SERDES_SPEED_28_125G;
                break;
            case DKIT_AT112G_SERDES_51P5625G :
                serdes_speed = DKIT_SERDES_SPEED_51_5625G;
                break;
            case DKIT_AT112G_SERDES_53P125G  :
                serdes_speed = DKIT_SERDES_SPEED_53_125G;
                break;
            case DKIT_AT112G_SERDES_56P25G   :
                serdes_speed = DKIT_SERDES_SPEED_56_25G;
                break;
            case DKIT_AT112G_SERDES_106GP25G :
                serdes_speed = DKIT_SERDES_SPEED_106_25G;
                break;
            case DKIT_AT112G_SERDES_112P5G   :
                serdes_speed = DKIT_SERDES_SPEED_112_5G;
                break;
            case DKIT_AT112G_SERDES_20P625G  :
                serdes_speed = DKIT_SERDES_SPEED_20_625G;
                break;
            case DKIT_AT112G_SERDES_11P40625G:
                serdes_speed = DKIT_SERDES_SPEED_11_40625G;
                break;
            case DKIT_AT112G_SERDES_10P9375G :
                serdes_speed = DKIT_SERDES_SPEED_10_9375G;
                break;
            case DKIT_AT112G_SERDES_12P96875G:
                serdes_speed = DKIT_SERDES_SPEED_12_96875G;
                break;
            case DKIT_AT112G_SERDES_27P34375G:
                serdes_speed = DKIT_SERDES_SPEED_27_34375G;
                break;
            case DKIT_AT112G_SERDES_27P78125G:
                serdes_speed = DKIT_SERDES_SPEED_27_78125G;
                break;
            case DKIT_AT112G_SERDES_112G     :
            case DKIT_AT112G_SERDES_1P0625G  :
            case DKIT_AT112G_SERDES_1P2288G  :
            case DKIT_AT112G_SERDES_2P125G   :
            case DKIT_AT112G_SERDES_2P4576G  :
            case DKIT_AT112G_SERDES_2P5G     :
            case DKIT_AT112G_SERDES_2P578125G:
            case DKIT_AT112G_SERDES_4P25G    :
            case DKIT_AT112G_SERDES_4P9152G  :
            case DKIT_AT112G_SERDES_5G       :
            case DKIT_AT112G_SERDES_5P15625G :
            case DKIT_AT112G_SERDES_6P144G   :
            case DKIT_AT112G_SERDES_6P25G    :
            case DKIT_AT112G_SERDES_7P5G     :
            case DKIT_AT112G_SERDES_8P5G     :
            case DKIT_AT112G_SERDES_9P8304G  :
            case DKIT_AT112G_SERDES_10P137G  :
            case DKIT_AT112G_SERDES_10P51875G:
            case DKIT_AT112G_SERDES_12P16512G:
            case DKIT_AT112G_SERDES_12P1875G :
            case DKIT_AT112G_SERDES_12P8906G :
            case DKIT_AT112G_SERDES_14P025G  :
            case DKIT_AT112G_SERDES_15G      :
            case DKIT_AT112G_SERDES_24P33024G:
            case DKIT_AT112G_SERDES_27P1875G :
            case DKIT_AT112G_SERDES_27P5G    :
            case DKIT_AT112G_SERDES_28P05G   :
            case DKIT_AT112G_SERDES_32P5G    :
            case DKIT_AT112G_SERDES_46P25G   :
            case DKIT_AT112G_SERDES_50G      :
            case DKIT_AT112G_SERDES_56G      :
            case DKIT_AT112G_SERDES_56P1G    :
            case DKIT_AT112G_SERDES_MAX_G    :
            default:
                serdes_speed = DKIT_SERDES_SPEED_0G;
                break;
        }
    }
    return serdes_speed;
}

void
_ctc_at_dkit_misc_get_div_exp10(uint64 a, uint64 b, uint32 rv_pos, uint64* p_val, uint64* p_e)
{
    uint32 pos = 0;

    if(a < b)
    {
        for(pos = 1; ; pos++)
        {
            a *= 10;
            if(a >= b) break;
        }
        *p_e = pos;
    }
    else
    {
        *p_e = 0;
    }

    for(pos = 0; pos < rv_pos; pos++)
    {
        a *= 10;
    }
    
    *p_val = a / b;

    return;
}

STATIC int32
_ctc_at_dkit_misc_serdes_prbs(uint8 lchip, void *p_data)
{
    sal_file_t p_file = NULL;
    ctc_dkit_at_serdes_ctl_prbs_t* p_prbs;
    ctc_at_dkit_serdes_dev_t       dev;
    uint8  cli_pattern;
    uint16 serdes_output;
#ifdef CTC_MATH_FLOATING
    /*double ber = 0;*/
    uint64 ber_v = 0;
    uint64 ber_e = 0;
#endif
    char* pattern[] = {"PRBS7", "PRBS7", "PRBS15", "PRBS15", "PRBS23", "PRBS23", "PRBS31", "PRBS31", "PRBS9", "Squareware(8081)", "PRBS11", "PRBS1T(1010)",
                        "PRBS13", "PRBS9", "PRBS13", "PRBS15", "PRBS31", "PRBS9", "PRBS13", "PRBS15", "PRBS31"};
    uint8 max_valid_pattern = 20;

    char* lane_rate[] = 
    {
        "0G       ", "1.25G    ", "3.125G   ", "10.3125G ",
        "11.40625G", "12.5G    ", "12.96875G", "10.9375G ", "20.625G",
        "25.78125G", "28.125G  ", "26.5625G ", "27.34375G",
        "27.78125G", "37.5G    ", "39.0625G ", "51.5625G ",
        "53.125G  ", "56.25G   ", "103.125G ", "106.25G  ", "112.5G   ", "42.5G"
    }; 
    uint8 tx_speed = 0;
    uint8 rx_speed = 0;

    ctc_dkit_monitor_task_t* p_mon_task = &(g_usw_dkit_master[lchip]->monitor_task[CTC_DKIT_MONITOR_TASK_PRBS_BER]);
    ctc_dkit_at_serdes_ber_mon_t* p_ber_mon = NULL;

    DKITS_PTR_VALID_CHECK(p_data);
    CTC_DKIT_LCHIP_CHECK(lchip);

    p_prbs = (ctc_dkit_at_serdes_ctl_prbs_t*)p_data;
    cli_pattern = p_prbs->pattern;
    if(cli_pattern > max_valid_pattern)
    {
        CTC_DKIT_PRINT("Invalid Pattern Param %d, Max:%d\n", cli_pattern, max_valid_pattern);
        return CLI_ERROR;
    }

    (void)_ctc_at_dkit_serdes_serdes_to_psd(lchip, p_prbs->serdes_id, &serdes_output);
    _ctc_at_dkit_serdes_dev(lchip, p_prbs->serdes_id, &dev);

    //p_prbs->pattern = _ctc_at_dkit_misc_serdes_prbs_pattern_convert(p_prbs->pattern);

    if(CTC_DKIT_SERDIS_CTL_DISABLE == p_prbs->oper)
    {
        _ctc_at_dkit_misc_serdes_ber_record_clear(lchip, p_prbs->serdes_id);

        if(p_mon_task->monitor_task)
        {
            p_ber_mon = (ctc_dkit_at_serdes_ber_mon_t*)p_mon_task->para;
            if(p_ber_mon && (0 == p_ber_mon->is_run))
            {
                p_mon_task->task_end = 1;
                sal_task_destroy(p_mon_task->monitor_task);
                p_mon_task->monitor_task = NULL;
                if(p_mon_task->para)
                {
                    mem_free(p_mon_task->para);
                    p_mon_task->para = NULL;
                }
            }
        }
    }

    (void)_ctc_at_dkit_misc_do_serdes_prbs(lchip, p_prbs);

    if(0 != p_prbs->str[0])
    {
        p_file = sal_fopen(p_prbs->str, "wt");
        if (!p_file)
        {
            CTC_DKIT_PRINT("Open file %s fail!!!\n", p_prbs->str);
            return CLI_ERROR;
        }
    }

    _ctc_at_dkit_get_txrx_rate(&dev, &tx_speed, &rx_speed);
    tx_speed = _ctc_at_dkit_serdes_get_related_serdes_speed(tx_speed, dev.type);
    rx_speed = _ctc_at_dkit_serdes_get_related_serdes_speed(rx_speed, dev.type);  

    if((CTC_DKIT_SERDIS_CTL_ENABLE == p_prbs->oper) || (CTC_DKIT_SERDIS_CTL_DISABLE == p_prbs->oper))
    {
        CTC_DKITS_PRINT_FILE(p_file, "\n%-12s%-6s%-10s%-20s%-9s\n", "Serdes_ID", "Dir", "LaneRate", "Pattern", "Enable");
        CTC_DKITS_PRINT_FILE(p_file, "------------------------------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_file, "%-12d%-6s%-10s%-20s%-9s\n", serdes_output, "TX", lane_rate[tx_speed], pattern[cli_pattern], 
            (CTC_DKIT_SERDIS_CTL_ENABLE == p_prbs->oper)? "Yes":"No");
    }
    else if (CTC_DKIT_SERDIS_CTL_CHECK == p_prbs->oper)
    {
        CTC_DKITS_PRINT_FILE(p_file, "\n%-12s%-6s%-10s%-10s%-16s %-16s%-9s\n", "Serdes_ID", "Dir", "LaneRate", "Pattern", "Total_cnt", "Err_cnt", "BER");
        CTC_DKITS_PRINT_FILE(p_file, "-------------------------------------------------------------------------------\n");
#ifdef CTC_MATH_FLOATING
        if((p_prbs->errcnt == 0) && (p_prbs->totcnt != 0))
        {
#ifdef UINT64_PRINT_FMT_LU
            CTC_DKITS_PRINT_FILE(p_file, "%-12d%-6s%-10s%-10s%-16lu %-16lu%-9s\n", 
                serdes_output, "RX", lane_rate[rx_speed], pattern[cli_pattern], p_prbs->totcnt, p_prbs->errcnt, "FREE");
#else
            CTC_DKITS_PRINT_FILE(p_file, "%-12d%-6s%-10s%-10s%-16ju %-16ju%-9s\n", 
                serdes_output, "RX", lane_rate[rx_speed], pattern[cli_pattern], p_prbs->totcnt, p_prbs->errcnt, "FREE");
#endif
        }
        else if(p_prbs->totcnt == 0)
        {
#ifdef UINT64_PRINT_FMT_LU
            CTC_DKITS_PRINT_FILE(p_file, "%-12d%-6s%-10s%-10s%-16lu %-16lu%-9s\n", 
                serdes_output, "RX", lane_rate[rx_speed], pattern[cli_pattern], p_prbs->totcnt, p_prbs->errcnt, "--");
#else
            CTC_DKITS_PRINT_FILE(p_file, "%-12d%-6s%-10s%-10s%-16ju %-16ju%-9s\n", 
                serdes_output, "RX", lane_rate[rx_speed], pattern[cli_pattern], p_prbs->totcnt, p_prbs->errcnt, "--");
#endif
        }
        else
        {
#ifdef UINT64_PRINT_FMT_LU
            /*ber = ((double)p_prbs->errcnt) / ((double)p_prbs->totcnt);
            CTC_DKITS_PRINT_FILE(p_file, "%-12d%-6s%-10s%-10s%-16ju %-16ju%-9.3e\n", 
                serdes_output, "RX", lane_rate[rx_speed], pattern[cli_pattern], p_prbs->totcnt, p_prbs->errcnt, ber);*/
            _ctc_at_dkit_misc_get_div_exp10(p_prbs->errcnt, p_prbs->totcnt, 2, &ber_v, &ber_e);
            CTC_DKITS_PRINT_FILE(p_file, "%-12d%-6s%-10s%-10s%-16lu %-16lu%lu.%02lue-%lu\n", 
                serdes_output, "RX", lane_rate[rx_speed], pattern[cli_pattern], p_prbs->totcnt, p_prbs->errcnt, ber_v/100, ber_v%100, ber_e);
#else
            /*ber = ((double)p_prbs->errcnt) / ((double)p_prbs->totcnt);
            CTC_DKITS_PRINT_FILE(p_file, "%-12d%-6s%-10s%-10s%-16ju %-16ju%-9.3e\n", 
                serdes_output, "RX", lane_rate[rx_speed], pattern[cli_pattern], p_prbs->totcnt, p_prbs->errcnt, ber);*/
            _ctc_at_dkit_misc_get_div_exp10(p_prbs->errcnt, p_prbs->totcnt, 2, &ber_v, &ber_e);
            CTC_DKITS_PRINT_FILE(p_file, "%-12d%-6s%-10s%-10s%-16ju %-16ju%ju.%02jue-%ju\n", 
                serdes_output, "RX", lane_rate[rx_speed], pattern[cli_pattern], p_prbs->totcnt, p_prbs->errcnt, ber_v/100, ber_v%100, ber_e);
#endif
        }
#else
#ifdef UINT64_PRINT_FMT_LU
        CTC_DKITS_PRINT_FILE(p_file, "%-12d%-6s%-10s%-10s%-16lu %-16lu%-9s\n", 
            serdes_output, "RX", lane_rate[rx_speed], pattern[cli_pattern], p_prbs->totcnt, p_prbs->errcnt, "--");
#else
        CTC_DKITS_PRINT_FILE(p_file, "%-12d%-6s%-10s%-10s%-16ju %-16ju%-9s\n", 
            serdes_output, "RX", lane_rate[rx_speed], pattern[cli_pattern], p_prbs->totcnt, p_prbs->errcnt, "--");
#endif
#endif
    }

    if (p_file)
    {
        sal_fclose(p_file);
    }

    return CLI_SUCCESS;
}

#define __SWITCH_SIMPLIFY__

uint8 _ctc_at_dkit_get_related_txrx_speed(uint8 serdes_speed, uint8 type)
{
    uint8 txrx_speed = 0;
    switch(serdes_speed)
    {
        case DKIT_SERDES_SPEED_1_25G    :
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_1P25G : DKIT_AT112G_SERDES_1P25G;
            break;
        case DKIT_SERDES_SPEED_3_125G   :
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_3P125G : DKIT_AT112G_SERDES_3P125G;
            break;
        case DKIT_SERDES_SPEED_10_3125G :
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_10P3125G : DKIT_AT112G_SERDES_10P3125G;
            break;
        case DKIT_SERDES_SPEED_11_40625G:
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_11P40625G : DKIT_AT112G_SERDES_11P40625G;
            break;
        case DKIT_SERDES_SPEED_12_5G    :
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_12P5G : DKIT_AT112G_SERDES_12P5G;
            break;
        case DKIT_SERDES_SPEED_12_96875G:
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_12P96875G : DKIT_AT112G_SERDES_12P96875G;
            break;
        case DKIT_SERDES_SPEED_10_9375G :
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_10P9375G : DKIT_AT112G_SERDES_10P9375G;
            break;
        case DKIT_SERDES_SPEED_25_78125G:
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_25P7812G : DKIT_AT112G_SERDES_25P78125G;
            break;
        case DKIT_SERDES_SPEED_28_125G  :
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_28P125G : DKIT_AT112G_SERDES_28P125G;
            break;
        case DKIT_SERDES_SPEED_26_5625G :
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_26P5625G : DKIT_AT112G_SERDES_26P5625G;
            break;
        case DKIT_SERDES_SPEED_27_34375G:
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_27P34375G : DKIT_AT112G_SERDES_27P34375G;
            break;
        case DKIT_SERDES_SPEED_27_78125G:
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_27P78125G : DKIT_AT112G_SERDES_27P78125G;
            break;
        case DKIT_SERDES_SPEED_37_5G    :
            ///TODO: not available
            break;
        case DKIT_SERDES_SPEED_39_0625G :
            ///TODO: not available
            break;
        case DKIT_SERDES_SPEED_51_5625G :
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_51P5625G : DKIT_AT112G_SERDES_51P5625G;
            break;
        case DKIT_SERDES_SPEED_53_125G  :
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_53P125G : DKIT_AT112G_SERDES_53P125G;
            break;
        case DKIT_SERDES_SPEED_56_25G   :
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_56P25G : DKIT_AT112G_SERDES_56P25G;
            break;
        case DKIT_SERDES_SPEED_103_125G :
            ///TODO: not available
            break;
        case DKIT_SERDES_SPEED_106_25G  :
            txrx_speed = DKIT_AT112G_SERDES_106GP25G;
            break;
        case DKIT_SERDES_SPEED_112_5G   :
            txrx_speed = DKIT_AT112G_SERDES_112P5G;
            break;
        case DKIT_SERDES_SPEED_0G       :
        default:
            txrx_speed = (CTC_AT_DKIT_SERDES_56G == type) ? DKIT_AT56G_SERDES_MAX_G : DKIT_AT112G_SERDES_MAX_G;
            break;
    }
    return txrx_speed;
}


void _ctc_at_dkit_set_rx_train_en(ctc_at_dkit_serdes_dev_t* p_dev, uint16 en)
{
    uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch(lane)
        {
            case 0:
                if(en) 
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN0, 0);
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN0, 1);
                }
                else
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN0, 0);
                    sal_udelay(1000);
                }
                break;
            case 1:
                if(en) 
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN1, 0);
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN1, 1);
                }
                else
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN1, 0);
                    sal_udelay(1000);
                }
                break;
            case 2:
                if(en) 
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN2, 0);
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN2, 1);
                }
                else
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN2, 0);
                    sal_udelay(1000);
                }
                break;
            case 3:
            default:
                if(en) 
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN3, 0);
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN3, 1);
                }
                else
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_TRAINEN3, 0);
                    sal_udelay(1000);
                }
                break;
        }
    }
    else
    {
        switch(lane)
        {
            case 0:
                if(en) 
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN0, 0);
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN0, 1);
                }
                else
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN0, 0);
                    sal_udelay(1000);
                }
                break;
            case 1:
                if(en) 
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN1, 0);
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN1, 1);
                }
                else
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN1, 0);
                    sal_udelay(1000);
                }
                break;
            case 2:
                if(en) 
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN2, 0);
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN2, 1);
                }
                else
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN2, 0);
                    sal_udelay(1000);
                }
                break;
            case 3:
            default:
                if(en) 
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN3, 0);
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN3, 1);
                }
                else
                {
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_TRAIN_EN3, 0);
                    sal_udelay(1000);
                }
                break;
        }
    }

    return;
}

void _ctc_at_dkit_set_lane_power(ctc_at_dkit_serdes_dev_t* p_dev, uint32 state)
{
    uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);
    uint16 pin[3]={};
    uint32 value[3];
    
    if(0 == state)
    {
        _ctc_at_dkit_set_rx_train_en(p_dev, 0);
    }

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch (lane)
        {
            case 0:
                pin[0] = DKIT_AT56G_PIN_PU_PLL0; 
                pin[1] = DKIT_AT56G_PIN_PU_TX0;
                pin[2] = DKIT_AT56G_PIN_PU_RX0;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                break;
            case 1:
                pin[0] = DKIT_AT56G_PIN_PU_PLL1; 
                pin[1] = DKIT_AT56G_PIN_PU_TX1;
                pin[2] = DKIT_AT56G_PIN_PU_RX1;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                break;
            case 2:
                pin[0] = DKIT_AT56G_PIN_PU_PLL2; 
                pin[1] = DKIT_AT56G_PIN_PU_TX2;
                pin[2] = DKIT_AT56G_PIN_PU_RX2;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                break;
            case 3:
                pin[0] = DKIT_AT56G_PIN_PU_PLL3; 
                pin[1] = DKIT_AT56G_PIN_PU_TX3;
                pin[2] = DKIT_AT56G_PIN_PU_RX3;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                break;
            default:
                return; /* Invalid lane */
        }
    }
    else
    {
        switch (lane)
        {
            case 0:
                pin[0] = DKIT_AT112G_PIN_PU_PLL0; 
                pin[1] = DKIT_AT112G_PIN_PU_TX0;
                pin[2] = DKIT_AT112G_PIN_PU_RX0;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                break;
            case 1:
                pin[0] = DKIT_AT112G_PIN_PU_PLL1; 
                pin[1] = DKIT_AT112G_PIN_PU_TX1;
                pin[2] = DKIT_AT112G_PIN_PU_RX1;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                break;
            case 2:
                pin[0] = DKIT_AT112G_PIN_PU_PLL2; 
                pin[1] = DKIT_AT112G_PIN_PU_TX2;
                pin[2] = DKIT_AT112G_PIN_PU_RX2;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                break;
            case 3:
                pin[0] = DKIT_AT112G_PIN_PU_PLL3; 
                pin[1] = DKIT_AT112G_PIN_PU_TX3;
                pin[2] = DKIT_AT112G_PIN_PU_RX3;
                value[0] = state;
                value[1] = state;
                value[2] = state;
                break;
            default:
                return; /* Invalid lane */
        }
    }
    _ctc_at_dkit_serdes_set_pin_array(p_dev, 3, pin, value);
}

uint8 _ctc_at_dkit_get_data_width_by_speed(ctc_at_dkit_serdes_dev_t* p_dev, uint8 serdes_speed)
{
    uint8  data_bus = 0;
    switch(serdes_speed)
    {
        case DKIT_SERDES_SPEED_1_25G    :
        case DKIT_SERDES_SPEED_3_125G   :
        case DKIT_SERDES_SPEED_10_3125G :
        case DKIT_SERDES_SPEED_11_40625G:
        case DKIT_SERDES_SPEED_12_5G    :
        case DKIT_SERDES_SPEED_12_96875G:
        case DKIT_SERDES_SPEED_10_9375G :
        case DKIT_SERDES_SPEED_20_625G:
        case DKIT_SERDES_SPEED_25_78125G:
        case DKIT_SERDES_SPEED_28_125G  :
        case DKIT_SERDES_SPEED_26_5625G :
        case DKIT_SERDES_SPEED_27_34375G:
        case DKIT_SERDES_SPEED_27_78125G:
            if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
            {
                data_bus = AT56G_DATABUS_32BIT;
            }
            else
            {
                data_bus = AT112G_DATABUS_32BIT;
            }
            break;
        case DKIT_SERDES_SPEED_51_5625G :
        case DKIT_SERDES_SPEED_53_125G  :
        case DKIT_SERDES_SPEED_56_25G   :
        case DKIT_SERDES_SPEED_42_5G   :
            if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
            {
                data_bus = AT56G_DATABUS_64BIT;
            }
            else
            {
                data_bus = AT112G_DATABUS_64BIT;
            }
            break;
        case DKIT_SERDES_SPEED_103_125G :
        case DKIT_SERDES_SPEED_106_25G  :
        case DKIT_SERDES_SPEED_112_5G   :
            if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
            {
                data_bus = 0xff; /*impossible*/
            }
            else
            {
                data_bus = AT112G_DATABUS_128BIT;
            }
            break;
        case DKIT_SERDES_SPEED_0G       :
        default:
            data_bus = 0xff;
            break;
    }
    return data_bus;
}

void _ctc_at_dkit_set_data_width(ctc_at_dkit_serdes_dev_t* p_dev, uint16 txWidth, uint16 rxWidth)
{
    uint32 txDataSelBits = 0, txDataPAM2En = 0;
    uint32 rxDataSelBits = 0, rxDataPAM2En = 0;

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        switch (txWidth)
        {
            case AT56G_DATABUS_80BIT:
                txDataSelBits = 0;
                txDataPAM2En  = 0;
                rxDataSelBits = 0;
                rxDataPAM2En  = 0;
                break;
            case AT56G_DATABUS_40BIT:
                txDataSelBits = 0;
                txDataPAM2En  = 1;
                rxDataSelBits = 0;
                rxDataPAM2En  = 1;
                break;
            case AT56G_DATABUS_64BIT:
                txDataSelBits = 1;
                txDataPAM2En  = 0;
                rxDataSelBits = 1;
                rxDataPAM2En  = 0;
                break;
            case AT56G_DATABUS_32BIT:
            default:
                txDataSelBits = 1;
                txDataPAM2En  = 1;
                rxDataSelBits = 1;
                rxDataPAM2En  = 1;
                break;
        }
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_SEL_BITS), 
            CTC_AT_DKIT_SERDES_REG_LANE, txDataSelBits);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_TX_PAM2_EN),  
            CTC_AT_DKIT_SERDES_REG_LANE, txDataPAM2En);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_SEL_BITS), 
            CTC_AT_DKIT_SERDES_REG_LANE, rxDataSelBits);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_PAM2_EN),  
            CTC_AT_DKIT_SERDES_REG_LANE, rxDataPAM2En);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_ANA_PAM2_EN),  
            CTC_AT_DKIT_SERDES_REG_LANE, rxDataPAM2En);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_RX_EQ_PAM2_EN),  
            CTC_AT_DKIT_SERDES_REG_LANE, rxDataPAM2En);
    }
    else
    {
        switch (txWidth)
        {
            case AT112G_DATABUS_160BIT:
            case AT112G_DATABUS_80BIT:
            case AT112G_DATABUS_40BIT:
                txDataSelBits = 0;
                rxDataSelBits = 0;
                break;
            case AT112G_DATABUS_128BIT:
            case AT112G_DATABUS_64BIT:
            case AT112G_DATABUS_32BIT:
            default:
                txDataSelBits = 1;
                rxDataSelBits = 1;
                break;
        }
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_TX_SEL_BITS), 
            CTC_AT_DKIT_SERDES_REG_LANE, txDataSelBits);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_RX_SEL_BITS), 
            CTC_AT_DKIT_SERDES_REG_LANE, rxDataSelBits);
    }
    return;
}

void
_ctc_at_dkit_set_graycode_en(ctc_at_dkit_serdes_dev_t* p_dev, uint8 dir, uint32 en)
{
    uint8 lane = CTC_DKIT_AT_SERDES_GET_LANE(p_dev->serdes_id);

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        if(0 == dir)
        {
            switch (lane)
            {
                case 0:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_GRAYCODE_EN0, en);
                    break;
                case 1:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_GRAYCODE_EN1, en);
                    break;
                case 2:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_GRAYCODE_EN2, en);
                    break;
                case 3:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_RX_GRAYCODE_EN3, en);
                    break;
                default:
                    return; /* Invalid lane */
            }
        }
        else
        {
            switch (lane)
            {
                case 0:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_GRAYCODE_EN0, en);
                    break;
                case 1:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_GRAYCODE_EN1, en);
                    break;
                case 2:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_GRAYCODE_EN2, en);
                    break;
                case 3:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT56G_PIN_TX_GRAYCODE_EN3, en);
                    break;
                default:
                    return; /* Invalid lane */
            }
        }
    }
    else
    {
        if(0 == dir)
        {
            switch (lane)
            {
                case 0:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_GRAYCODE_EN0, en);
                    break;
                case 1:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_GRAYCODE_EN1, en);
                    break;
                case 2:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_GRAYCODE_EN2, en);
                    break;
                case 3:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_RX_GRAYCODE_EN3, en);
                    break;
                default:
                    return; /* Invalid lane */
            }
        }
        else
        {
            switch (lane)
            {
                case 0:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_GRAYCODE_EN0, en);
                    break;
                case 1:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_GRAYCODE_EN1, en);
                    break;
                case 2:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_GRAYCODE_EN2, en);
                    break;
                case 3:
                    _ctc_at_dkit_serdes_set_pin(p_dev, DKIT_AT112G_PIN_TX_GRAYCODE_EN3, en);
                    break;
                default:
                    return; /* Invalid lane */
            }
        }
    }

    return;
}


void 
_ctc_at_dkit_speed_switch_simplify(uint8 lchip, uint16 serdes_id, uint8 serdes_speed)
{
    ctc_at_dkit_serdes_dev_t dev = {0};
    uint8 txrx_speed;
    uint16 txrx_width;

    _ctc_at_dkit_serdes_dev(lchip, serdes_id, &dev);    

    txrx_speed = _ctc_at_dkit_get_related_txrx_speed(serdes_speed, dev.type);
#if 0
    /* Disable TX Output for all lanes */
    _ctc_at_dkit_set_tx_en(&dev, 0);
    
    /* Configure TX and RX bitrates for all lanes */
    _ctc_at_dkit_set_txrx_rate(&dev, txrx_speed, txrx_speed);

    /* Power on PHY PLLs, Transmitter and Receiver for all lanes*/
    (void)_ctc_at_dkit_wait_pllready(&dev);

    /* Toggle RX_INIT */
    _ctc_at_dkit_rx_init(&dev);

    /* Enable TX Output for all lanes */
    _ctc_at_dkit_set_tx_en(&dev, 1);
#endif
    /*1. set lane power down*/
    _ctc_at_dkit_set_lane_power(&dev, 0);

    /*2. set reset 1*/
    /*2.1 set txrx reset 1*/
    _ctc_at_dkit_set_txrx_reset(&dev, 1);
    /*2.2 wait txrx rstdone 0*/
    _ctc_at_dkit_wait_txrx_rstdone(&dev);
    /*2.3 set txrx reset 0*/
    _ctc_at_dkit_set_txrx_reset(&dev, 0);

    /*3. set new speed*/
    /*3.1 set databus width*/
    txrx_width = _ctc_at_dkit_get_data_width_by_speed(&dev, serdes_speed);
    _ctc_at_dkit_set_data_width(&dev, txrx_width, txrx_width);
    /*3.2 set graycode en*/
    if(CTC_DKIT_AT_IS_SERDES_SPEED_PAM4(serdes_speed))
    {
        _ctc_at_dkit_set_graycode_en(&dev, 0, 1);
        _ctc_at_dkit_set_graycode_en(&dev, 1, 1);
    }
    else
    {
        _ctc_at_dkit_set_graycode_en(&dev, 0, 0);
        _ctc_at_dkit_set_graycode_en(&dev, 1, 0);
    }
    /*3.3 set txrx bit rate*/
    _ctc_at_dkit_set_txrx_rate(&dev, txrx_speed, txrx_speed);
    
    /*4. set lane power up*/
    _ctc_at_dkit_set_lane_power(&dev, 1);
    
    /*5. wait txrx pll ready*/
    (void)_ctc_at_dkit_wait_pllready(&dev);
    
    /*6. set rx init*/
    _ctc_at_dkit_rx_init(&dev);
}


#define __EOM__

void _ctc_at_dkit_misc_serdes_eye_mon_plot(ctc_at_dkit_serdes_dev_t* p_dev)
{
    uint32 min_samples = 0;
    uint32 ber_thrd = 0; 
    uint32 min_samples_sub = 0; 
    uint32 berThreshold_sub = 0;
    uint8 eom_stats_mode = 0;
    uint32 voltageStepSize = 1;
    uint32 phaseStepSize = 1; 
    uint32 i, j;
    uint8 modulation;

    modulation = _ctc_at_dkit_get_serdes_modulation_mode(p_dev);
    
    _ctc_at_dkit_eom_get_meas_para(DKIT_EOM_PRECISION_L3, &min_samples, &ber_thrd);
    _ctc_at_dkit_eom_get_meas_para(DKIT_EOM_PRECISION_L1, &min_samples_sub, &berThreshold_sub);

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _dkit_at_serdes_56g_eom_data_t* eom_data = (_dkit_at_serdes_56g_eom_data_t*)mem_malloc(MEM_SYSTEM_MODULE, sizeof(_dkit_at_serdes_56g_eom_data_t));
        if(NULL == eom_data)
        {
            return;
        }
        sal_memset(eom_data, 0, sizeof(_dkit_at_serdes_56g_eom_data_t));
        for(i = 0; i < DKIT_AT56G_EYE_MAX_PHASE_LEVEL; i++)
        {
            for(j = 0; j < (DKIT_AT56G_EYE_MAX_VOLT_STEPS * 2) - 1; j++)
            {
                eom_data->eyeRawData[i][j] = min_samples;
            }
        }
        if(CTC_DKIT_AT_SERDES_PAM4_MODE == modulation)
        {
            CTC_DKIT_PRINT(" Map Eye Top\n\n");
            if(CLI_SUCCESS != _ctc_at_dkit_eom_get_eye_data(p_dev, DKIT_EYE_TOP, min_samples, ber_thrd, eom_stats_mode, (void*)eom_data))
            {
                mem_free(eom_data);
                return;
            }
            _ctc_at_dkit_eom_plot_eye_data(p_dev, voltageStepSize, phaseStepSize, min_samples, min_samples_sub, 
                berThreshold_sub, ber_thrd, (void*)eom_data);

            CTC_DKIT_PRINT(" Map Eye Mid\n\n");
            for(i = 0; i < DKIT_AT56G_EYE_MAX_PHASE_LEVEL; i++)
            {
                for(j = 0; j < (DKIT_AT56G_EYE_MAX_VOLT_STEPS * 2) - 1; j++)
                {
                    eom_data->eyeRawData[i][j] = min_samples;
                }
            }
            if(CLI_SUCCESS != _ctc_at_dkit_eom_get_eye_data(p_dev, DKIT_EYE_MID, min_samples, ber_thrd, eom_stats_mode, (void*)eom_data))
            {
                mem_free(eom_data);
                return;
            }
            _ctc_at_dkit_eom_plot_eye_data(p_dev, voltageStepSize, phaseStepSize, min_samples, min_samples_sub, 
                berThreshold_sub, ber_thrd, (void*)eom_data);

            CTC_DKIT_PRINT(" Map Eye Bot\n\n");
            for(i = 0; i < DKIT_AT56G_EYE_MAX_PHASE_LEVEL; i++)
            {
                for(j = 0; j < (DKIT_AT56G_EYE_MAX_VOLT_STEPS * 2) - 1; j++)
                {
                    eom_data->eyeRawData[i][j] = min_samples;
                }
            }
            if(CLI_SUCCESS != _ctc_at_dkit_eom_get_eye_data(p_dev, DKIT_EYE_BOT, min_samples, ber_thrd, eom_stats_mode, (void*)eom_data))
            {
                mem_free(eom_data);
                return;
            }
            _ctc_at_dkit_eom_plot_eye_data(p_dev, voltageStepSize, phaseStepSize, min_samples, min_samples_sub, 
                berThreshold_sub, ber_thrd, (void*)eom_data);
        }
        else
        {
            if(CLI_SUCCESS != _ctc_at_dkit_eom_get_eye_data(p_dev, DKIT_EYE_MID, min_samples, ber_thrd, eom_stats_mode, (void*)eom_data))
            {
                mem_free(eom_data);
                return;
            }
            _ctc_at_dkit_eom_plot_eye_data(p_dev, voltageStepSize, phaseStepSize, min_samples, min_samples_sub, 
                berThreshold_sub, ber_thrd, (void*)eom_data);
        }
        mem_free(eom_data);
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _dkit_at_serdes_112g_eom_data_t* eom_data = (_dkit_at_serdes_112g_eom_data_t*)mem_malloc(MEM_SYSTEM_MODULE, sizeof(_dkit_at_serdes_112g_eom_data_t));
        if(NULL == eom_data)
        {
            return;
        }
        sal_memset(eom_data, 0, sizeof(_dkit_at_serdes_112g_eom_data_t));
        for(i = 0; i < DKIT_AT112G_EYE_MAX_PHASE_LEVEL*2+1; i++)
        {
            for(j = 0; j < DKIT_AT112G_EYE_PAM2_VOLT_STEPS*2+1; j++)
            {
                eom_data->eyeRawData[i][j] = min_samples;
            }
        }
        if(CTC_DKIT_AT_SERDES_PAM4_MODE == modulation)
        {
            CTC_DKIT_PRINT(" Map Eye Top\n\n");
            if(CLI_SUCCESS != _ctc_at_dkit_eom_get_eye_data(p_dev, DKIT_EYE_TOP, min_samples, ber_thrd, eom_stats_mode, (void*)eom_data))
            {
                mem_free(eom_data);
                return;
            }
            _ctc_at_dkit_eom_plot_eye_data(p_dev, voltageStepSize, phaseStepSize, min_samples, min_samples_sub, 
                berThreshold_sub, ber_thrd, (void*)eom_data);

            CTC_DKIT_PRINT(" Map Eye Mid\n\n");
            for(i = 0; i < DKIT_AT112G_EYE_MAX_PHASE_LEVEL*2+1; i++)
            {
                for(j = 0; j < DKIT_AT112G_EYE_PAM2_VOLT_STEPS*2+1; j++)
                {
                    eom_data->eyeRawData[i][j] = min_samples;
                }
            }
            if(CLI_SUCCESS != _ctc_at_dkit_eom_get_eye_data(p_dev, DKIT_EYE_MID, min_samples, ber_thrd, eom_stats_mode, (void*)eom_data))
            {
                mem_free(eom_data);
                return;
            }
            _ctc_at_dkit_eom_plot_eye_data(p_dev, voltageStepSize, phaseStepSize, min_samples, min_samples_sub, 
                berThreshold_sub, ber_thrd, (void*)eom_data);

            CTC_DKIT_PRINT(" Map Eye Bot\n\n");
            for(i = 0; i < DKIT_AT112G_EYE_MAX_PHASE_LEVEL*2+1; i++)
            {
                for(j = 0; j < DKIT_AT112G_EYE_PAM2_VOLT_STEPS*2+1; j++)
                {
                    eom_data->eyeRawData[i][j] = min_samples;
                }
            }
            if(CLI_SUCCESS != _ctc_at_dkit_eom_get_eye_data(p_dev, DKIT_EYE_BOT, min_samples, ber_thrd, eom_stats_mode, (void*)eom_data))
            {
                mem_free(eom_data);
                return;
            }
            _ctc_at_dkit_eom_plot_eye_data(p_dev, voltageStepSize, phaseStepSize, min_samples, min_samples_sub, 
                berThreshold_sub, ber_thrd, (void*)eom_data);
        }
        else
        {
            if(CLI_SUCCESS != _ctc_at_dkit_eom_get_eye_data(p_dev, DKIT_EYE_MID, min_samples, ber_thrd, eom_stats_mode, (void*)eom_data))
            {
                mem_free(eom_data);
                return;
            }
            _ctc_at_dkit_eom_plot_eye_data(p_dev, voltageStepSize, phaseStepSize, min_samples, min_samples_sub, 
                berThreshold_sub, ber_thrd, (void*)eom_data);
        }
        mem_free(eom_data);
    }
}

STATIC int32
_ctc_at_dkit_misc_serdes_eye(uint8 lchip, void *p_data)
{
    uint32 index = 0, n = 0;
    uint32 times = 0;
    uint32 eye_margin = 0;
    uint16 eye_width = 0;
    uint32 eye_min = 0xffff;
    uint32 eye_max = 0;
    uint32 ew_min = 0xffff;
    uint32 ew_max = 0;
    uint32 eye3_margin[3] = {0,0,0};
    uint32 eye3_min[3] = {0xffff, 0xffff, 0xffff};
    uint32 eye3_max[3] = {0,0,0};
    uint32 eye3_sum[3] = {0,0,0};
    uint32 sum = 0;
    uint32 sum_w = 0;
    uint8  tmb = 0;
    uint8  tx_ready = 0;
    uint8  rx_ready = 0;
    uint8  sq = 0;
    
    ctc_dkit_at_serdes_ctl_eye_t *p_eye;
    ctc_at_dkit_serdes_dev_t dev;
    _dkit_at_serdes_56g_eom_margin_t margin_56g;
    _dkit_at_serdes_112g_eom_margin_t margin_112g;
    
    DKITS_PTR_VALID_CHECK(p_data);
    CTC_DKIT_LCHIP_CHECK(lchip);

    p_eye = (ctc_dkit_at_serdes_ctl_eye_t *)p_data;
    
    _ctc_at_dkit_serdes_dev(lchip, p_eye->serdes_id, &dev);

    _ctc_at_dkit_get_txrx_ready(&dev, &tx_ready, &rx_ready);
    if(0 == rx_ready)
    {
        CTC_DKIT_PRINT(" EOM fail, pll rx ready = 0\n");
        return CLI_SUCCESS;
    }
    _ctc_at_dkit_get_sq_det(&dev, &sq);
    if(1 == sq)
    {
        CTC_DKIT_PRINT(" EOM fail, signal detect = 0\n");
        return CLI_SUCCESS;
    }

    if((CTC_DKIT_SERDIS_EYE_HEIGHT == p_eye->eye_type) || (CTC_DKIT_SERDIS_EYE_WIDTH == p_eye->eye_type) || (CTC_DKIT_SERDIS_EYE_ALL == p_eye->eye_type))
    {
        /*current in 56g ip , support min_sample & ber_thrd feature */
        if(CTC_AT_DKIT_SERDES_56G == dev.type)
        {
            _ctc_at_dkit_eom_get_meas_para(DKIT_EOM_PRECISION_L3, &margin_56g.min_samples, &margin_56g.ber_thrd);
            margin_56g.eye_tmb = DKIT_EYE_MID;
        }
        else
        {
            _ctc_at_dkit_eom_get_meas_para(DKIT_EOM_PRECISION_L3, &margin_112g.min_samples, &margin_112g.ber_thrd);
            margin_112g.eye_tmb = DKIT_EYE_MID;
        }    

        times = p_eye->read_times;
        if(0 == times)
        {
            times = 1;
        }
        
        if(CTC_DKIT_AT_SERDES_NRZ_MODE == _ctc_at_dkit_get_serdes_modulation_mode(&dev))
        {
            
            CTC_DKIT_PRINT(" ---------------------------------------------------------------\n");
            CTC_DKIT_PRINT(" %-10s%-10s%-10s\n", "No.", "EyeOpen", "EyeWidth");
            CTC_DKIT_PRINT(" ---------------------------------------------------------------\n");
            for(index = 0; index < times; index ++)
            {
                if(CTC_AT_DKIT_SERDES_56G == dev.type)
                {
                    _ctc_at_dkit_eom_get_width_height(&dev, (void*)&margin_56g);
                    eye_margin = (uint32)margin_56g.height_lower + margin_56g.height_upper;
                    eye_width = margin_56g.width;
                }
                else
                {
                    _ctc_at_dkit_eom_get_width_height(&dev, (void*)&margin_112g);
                    eye_margin = (uint32)margin_112g.height_lower + margin_112g.height_upper;
                    eye_width = margin_56g.width;
                }
            
                sum += eye_margin;
                sum_w += eye_width;
                
                eye_max = (eye_margin > eye_max ? eye_margin : eye_max);
                eye_min = (eye_margin < eye_min ? eye_margin : eye_min);
                ew_max = (eye_width > ew_max ? eye_width : ew_max);
                ew_min = (eye_width < ew_min ? eye_width : ew_min);
    
                CTC_DKIT_PRINT(" %-10u%-10u%-10u\n", index + 1, eye_margin, eye_width);
            }
    
            CTC_DKIT_PRINT(" ---------------------------------------------------------------\n");
            CTC_DKIT_PRINT(" %-10s%-10u%-10u\n","Min", eye_min, ew_min);
            CTC_DKIT_PRINT(" %-10s%-10u%-10u\n","Max", eye_max, ew_max);
            CTC_DKIT_PRINT(" %-10s%-10u%-10u\n","Avg", (sum/times), (sum_w/times));
        }
        else
        {
            CTC_DKIT_PRINT(" ---------------------------------------------------------------\n");
            CTC_DKIT_PRINT(" %-10s  %-10s  %-10s  %-10s  \n", "No.", "Eye1_Open","Eye2_Open","Eye3_Open");
            CTC_DKIT_PRINT(" ---------------------------------------------------------------\n");
            for(index = 0; index < times; index ++)
            {
                for(tmb = DKIT_EYE_BOT; tmb < DKIT_EYE_TMB_BUTT; tmb++)
                {
                    if(CTC_AT_DKIT_SERDES_56G == dev.type)
                    {
                        margin_56g.eye_tmb = tmb;
                        _ctc_at_dkit_eom_get_width_height(&dev, (void*)&margin_56g);    
                        eye3_margin[tmb] = (uint32)margin_56g.height_lower + margin_56g.height_lower;
                    }
                    else
                    {
                        margin_112g.eye_tmb = tmb;
                        _ctc_at_dkit_eom_get_width_height(&dev, (void*)&margin_112g);
                        eye3_margin[tmb] = (uint32)margin_112g.height_lower + margin_112g.height_upper;
                    }
                    
                }
                
                for(n = 0; n < 3; n ++)
                {
                    eye3_sum[n] += eye3_margin[n];
                    eye3_max[n] = (eye3_margin[n] > eye3_max[n] ? eye3_margin[n] : eye3_max[n]);
                    eye3_min[n] = (eye3_margin[n] < eye3_min[n] ? eye3_margin[n] : eye3_min[n]);
                }

                CTC_DKIT_PRINT(" %-10d  %-10d  %-10d  %-10d  \n", index + 1, eye3_margin[0], eye3_margin[1], eye3_margin[2]);
            }

            CTC_DKIT_PRINT(" ---------------------------------------------------------------\n");
            CTC_DKIT_PRINT(" %-10s  %-10d  %-10d  %-10d  \n","Min", eye3_min[0], eye3_min[1], eye3_min[2]);
            CTC_DKIT_PRINT(" %-10s  %-10d  %-10d  %-10d  \n", "Max", eye3_max[0], eye3_max[1], eye3_max[2]);
            CTC_DKIT_PRINT(" %-10s  %-10d  %-10d  %-10d  \n","Avg", eye3_sum[0] / times, eye3_sum[1] / times, eye3_sum[2] / times);
        }
        
    }

    if(CTC_DKIT_SERDIS_EYE_WIDTH_SLOW == p_eye->eye_type)
    {
        _ctc_at_dkit_misc_serdes_eye_mon_plot(&dev);
    }

    return CLI_SUCCESS;
}

int32
ctc_at_dkit_misc_serdes_dump(uint8 lchip, uint16 serdes_id, uint32 dump_level, char* file_name)
{
    sal_file_t p_file = NULL;
    char* p_time_str = NULL;
    sal_time_t tv;
    uint32 addr;
    uint32 data = 0;
    uint8  reg_list_idx;
    uint8  pin_idx;
    uint16 val_u16;
    uint16 psd;
    uint8 tx_ready,rx_ready;
    uint8 power_pll, power_tx, power_rx, power_ivref;
    uint16 txfreq, rxfreq, txclksel, rxclksel;
    uint16 txwidth, rxwidth;
    uint16 freq_mhz;
    uint32 temperature;
    uint8 tx_en;
    uint8 sq_det;
    uint16 sq_thrd;
    uint8 ext_loopback, int_dig_loopback, int_ana_loopback;
    uint8 tx_swap, rx_swap;
    uint8 tx_graycode, rx_graycode, tx_precode, rx_precode;
    uint8 cdr_lock, clamp;
    uint32 dfe_en;
    uint8  modulation;
    uint32 snr_db;
    uint32 snr_reg;
    uint8 tx_speed, rx_speed;
    uint32 prbs_tx_en, prbs_tx_pat, prbs_rx_en, prbs_rx_pat;
    uint32 tx_polarity, rx_polarity;
    uint8  dfe_freeze;
    uint8 timeout_en_rx, timeout_en_trx;
    uint16 timeout_rx, timeout_trx; 
    ctc_at_dkit_serdes_dev_t dev;
    uint32 tbl_id,fld_id;
    char tbl_name[32];
    char* ptr_field_name = NULL;
    ctc_dkit_at_serdes_ctl_eye_t eye_data;
    _dkit_at_serdes_56g_ffe_tap_t*  p_ffe_tap_56g;
    _dkit_at_serdes_112g_ffe_tap_t* p_ffe_tap_112g;
    _dkit_at_serdes_56g_dfe_tap_param_t*  p_dfe_tap_56g;
    _dkit_at_serdes_112g_ffe_tap_param_t* p_dfe_tap_112g;
    _dkit_at_serdes_56g_ctle_param_t*   p_ctle_tap_56g;
    _dkit_at_serdes_112g_ctle_param_t*  p_ctle_tap_112g;
    
    char* databus[] =
    {
        "32BIT",
        "40BIT",
        "64BIT",
        "80BIT",
        "128BIT",
        "160BIT",    
    };

    char* msblsb_swap[] = {
        "DISABLE",
        "PRECODER",
        "POSTCODER"
    };

    char* serdes_speed[] = 
    {
        "0G       ",
        "1.25G    ",
        "3.125G   ",
        "10.3125G ",
        "11.40625G",
        "12.5G    ",
        "12.96875G",
        "10.9375G ",
        "20.625G  ",
        "25.78125G",
        "28.125G  ",
        "26.5625G ",
        "27.34375G",
        "27.78125G",
        "37.5G    ",
        "39.0625G ",
        "51.5625G ",
        "53.125G  ",
        "56.25G   ",
        "103.125G ",
        "106.25G  ",
        "112.5G   ",
        "42.5G    "
    }; 

    char* prbs_pattern[19] = 
    {
       "PRBS7", "PRBS7", "PRBS15", "PRBS15", "PRBS23", "PRBS23", "PRBS31", "PRBS31",
       "PRBS9", "PRBS13", "PRBS9", "PRBS13", "PRBS15", "PRBS31", "PRBS9", "PRBS13", "PRBS15", "PRBS31", "NONE",
    };

    DKITS_SERDES_ID_CHECK(lchip,serdes_id);
    CTC_DKIT_LCHIP_CHECK(lchip);

    if (file_name)
    {
        p_file = sal_fopen(file_name, "wt");
        if (!p_file)
        {
            CTC_DKIT_PRINT("Open file %s fail!!!\n", file_name);
            
        }
    }
    
    sal_time(&tv);
    p_time_str = sal_ctime(&tv);
    CTC_DKITS_PRINT_FILE(p_file, "# Serdes %d config & status dump, %s", serdes_id, p_time_str);

    /* user serdes id to psd */
    (void)_ctc_at_dkit_serdes_serdes_to_psd(lchip, serdes_id, &psd);
    _ctc_at_dkit_serdes_dev(lchip, psd, &dev);

    _ctc_at_dkit_get_temperature(&dev, &temperature);
    _ctc_at_dkit_get_power_pll(&dev, &power_pll);
    _ctc_at_dkit_get_power_txrx(&dev, DKIT_AT_DIR_TX, &power_tx);
    _ctc_at_dkit_get_power_txrx(&dev, DKIT_AT_DIR_RX, &power_rx);
    _ctc_at_dkit_get_power_ivref(&dev, &power_ivref);
    _ctc_at_dkit_get_ref_freq(&dev, &txfreq, &rxfreq, &txclksel, &rxclksel);
    _ctc_at_dkit_get_data_width(&dev, &txwidth, &rxwidth);
    _ctc_at_dkit_get_mcu_freq(&dev, &freq_mhz);
    _ctc_at_dkit_get_tx_en(&dev, &tx_en);
    _ctc_at_dkit_get_sq_det(&dev, &sq_det);
    _ctc_at_dkit_get_sq_thrd(&dev, &sq_thrd);
    _ctc_at_dkit_serdes_get_loopback(&dev, DKIT_AT_LOOPBACK_INTERNAL, &int_dig_loopback);
    _ctc_at_dkit_serdes_get_loopback(&dev, DKIT_AT_LOOPBACK_EXTERNAL, &ext_loopback);
    _ctc_at_dkit_serdes_get_loopback(&dev, DKIT_AT_LOOPBACK_LOCAL_ANALOG, &int_ana_loopback);
    _ctc_at_dkit_get_msb_lsb_swap(&dev, &tx_swap, &rx_swap);
    _ctc_at_dkit_get_txrx_rate(&dev, &tx_speed, &rx_speed);
    tx_speed = _ctc_at_dkit_serdes_get_related_serdes_speed(tx_speed, dev.type);
    rx_speed = _ctc_at_dkit_serdes_get_related_serdes_speed(rx_speed, dev.type);    
    _ctc_at_dkit_get_graycode(&dev, &tx_graycode, &rx_graycode);
    _ctc_at_dkit_get_precode(&dev, &tx_precode, &rx_precode);
    _ctc_at_dkit_get_cdr_lock(&dev, &cdr_lock, &clamp);
    _ctc_at_dkit_get_dfe_enable(&dev, &dfe_en);
    if(1 == sq_det)
    {
        snr_db = 0;
        snr_reg = 0;
    }
    else
    {
        _ctc_at_dkit_get_snr(&dev, &snr_db, &snr_reg);
    }
    _ctc_at_dkit_get_prbs_en(&dev, DKIT_AT_DIR_TX, &prbs_tx_en);
    _ctc_at_dkit_get_prbs_pattern(&dev, DKIT_AT_DIR_TX, &prbs_tx_pat);
    prbs_tx_pat = prbs_tx_pat > 18 ? 18 : prbs_tx_pat;
    _ctc_at_dkit_get_prbs_en(&dev, DKIT_AT_DIR_RX, &prbs_rx_en);
    _ctc_at_dkit_get_prbs_pattern(&dev, DKIT_AT_DIR_RX, &prbs_rx_pat);
    prbs_rx_pat = prbs_rx_pat > 18 ? 18 : prbs_rx_pat;
    _ctc_at_dkit_get_txrx_polarity(&dev, &tx_polarity, &rx_polarity);
    _ctc_at_dkit_get_dfe_freeze_updates(&dev, &dfe_freeze);
    _ctc_at_dkit_get_training_timeout(&dev, DKIT_AT_TRAINING_RX,  &timeout_en_rx, &timeout_rx);
    _ctc_at_dkit_get_training_timeout(&dev, DKIT_AT_TRAINING_TRX, &timeout_en_trx, &timeout_trx);

    modulation = _ctc_at_dkit_get_serdes_modulation_mode(&dev);

    /*_ctc_at_dkit_get_pll_lock(&dev, &tx_lock, &rx_lock);*/
    _ctc_at_dkit_get_txrx_ready(&dev, &tx_ready, &rx_ready);
    
    CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
    CTC_DKITS_PRINT_FILE(p_file, " SerDes Dev Info\n");
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10s\n", "Type", (dev.type == CTC_AT_DKIT_SERDES_56G) ? "56G" : "112G");
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "HSS inst", CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(psd));
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "HSS lane", CTC_DKIT_AT_SERDES_GET_LANE(psd));
    CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%u.%u C\n", "Temperature", (temperature/10000), (temperature%10000));
    CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
    CTC_DKITS_PRINT_FILE(p_file, " PowerUp\n");
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "POWER-IVREF", power_ivref);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "POWER-PLL", power_pll);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "POWER-TX", power_tx);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "POWER-RX", power_rx);
    CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
    CTC_DKITS_PRINT_FILE(p_file, " RefClk\n");
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "TX-FREQ", txfreq);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "TXCLK-SEL", txclksel);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "RX-FREQ", rxfreq);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "RXCLK-SEL", rxclksel);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d(MHZ)\n", "MCU-FREQ", freq_mhz);
    CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
    CTC_DKITS_PRINT_FILE(p_file, " DataBusWidth\n");
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10s\n", "TX-WIDTH", databus[txwidth]);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10s\n", "RX-WIDTH", databus[rxwidth]);
    CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
    CTC_DKITS_PRINT_FILE(p_file, " SerDes Status\n");
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "PLL_TX_READY", tx_ready);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "PLL_RX_READY", rx_ready);
    if(CTC_AT_DKIT_SERDES_56G== dev.type)
    {
        _ctc_at_dkit_serdes_read_reg_field(&dev, DKIT_REG_STR(F_DKIT_AT56G_PLL_SEL_LANE), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    }
    else
    {
        _ctc_at_dkit_serdes_read_reg_field(&dev, DKIT_REG_STR(F_DKIT_AT112G_PLL_SEL_LANE), CTC_AT_DKIT_SERDES_REG_LANE, &data);
    }
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%u (%s)\n", "PLL_SEL_LANE", data, ((data==2) ? "RS" : "TS"));
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "SQ-DET", sq_det);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "SQ-THRD", sq_thrd);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "CDR-LOCK", cdr_lock);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "DTL-CLAMP", clamp);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%u.%u %s (raw value %u)\n", "SNR", snr_db/1000, snr_db%1000, "dB", snr_reg);
    CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
    CTC_DKITS_PRINT_FILE(p_file, " Loopback config\n");
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "INT-DIGITAL", int_dig_loopback);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "INT-ANALOG", int_ana_loopback);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "EXT", ext_loopback);
    CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
    CTC_DKITS_PRINT_FILE(p_file, " PAM4 Coding config\n");
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "TX-GRAYCODE", tx_graycode);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "RX-GRAYCODE", rx_graycode);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "TX-PRECODE", tx_precode);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "RX-PRECODE", rx_precode);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10s\n", "TX-MSBLSB", msblsb_swap[tx_swap]);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10s\n", "RX-MSBLSB", msblsb_swap[rx_swap]);
    CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
    CTC_DKITS_PRINT_FILE(p_file, " PRBS config\n");
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "TX-EN", prbs_tx_en);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10s\n", "TX-PATTERN", prbs_pattern[prbs_tx_pat]);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "RX-EN", prbs_rx_en);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10s\n", "RX-PATTERN", prbs_pattern[prbs_rx_pat]);
    CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
    CTC_DKITS_PRINT_FILE(p_file, " Polarity config\n");
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10s\n", "TX", (tx_polarity) ? "INVERSE" : "NORMAL");
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10s\n", "RX", (rx_polarity) ? "INVERSE" : "NORMAL");
    CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
    CTC_DKITS_PRINT_FILE(p_file, " Link Training config\n");
    if(timeout_en_rx)
    {
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10dms\n", "RX-TRAIN TIMEOUT", timeout_rx);
    }
    else
    {
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10s\n", "RX-TRAIN TIMEOUT", "disable");
    }
    if(timeout_en_trx)
    {
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10dms\n", "TRX-TRAIN TIMEOUT", timeout_trx);
    }
    else
    {
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10s\n", "TRX-TRAIN TIMEOUT", "disable");
    }
    CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
    CTC_DKITS_PRINT_FILE(p_file, " SerDes %d Params \n", serdes_id);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10s\n", "TX-SPEED", serdes_speed[tx_speed]);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10s\n", "RX-SPEED", serdes_speed[rx_speed]);
    CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10s\n", "TX-IDLE", (tx_en == 0) ? "IDLE" : "WORK");
    CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
    CTC_DKITS_PRINT_FILE(p_file, " RX FFE / DFE config\n");
    if(CTC_AT_DKIT_SERDES_56G== dev.type)
    {
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10u\n", "EN", dfe_en);   
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10u\n", "FREEZE", dfe_freeze);
        
        p_dfe_tap_56g = (_dkit_at_serdes_56g_dfe_tap_param_t*)mem_malloc(MEM_CLI_MODULE, sizeof(_dkit_at_serdes_56g_dfe_tap_param_t));
        if(NULL == p_dfe_tap_56g)
        {
            if (p_file) { sal_fclose(p_file); }
            return CLI_ERROR;
        }
        sal_memset(p_dfe_tap_56g, 0, sizeof(_dkit_at_serdes_56g_dfe_tap_param_t));

        _ctc_at_dkit_get_dfe_freeze_updates(&dev, &dfe_freeze);
        _ctc_at_dkit_set_dfe_freeze_updates(&dev, 1);
        
        if(CTC_DKIT_AT_SERDES_PAM4_MODE == modulation)
        {
            _ctc_at_dkit_get_dfe_tap(&dev, DKIT_EYE_BOT, (void*)p_dfe_tap_56g);
            CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "DFE TAP[BOT]", "DC", p_dfe_tap_56g->dkit_dfe_tap_dc, "VREF", p_dfe_tap_56g->dkit_dfe_tap_vref,
            "F0", p_dfe_tap_56g->dkit_dfe_tap_f0, "F1", p_dfe_tap_56g->dkit_dfe_tap_f0, "F2", p_dfe_tap_56g->dkit_dfe_tap_f2);
            _ctc_at_dkit_get_dfe_tap(&dev, DKIT_EYE_MID, (void*)p_dfe_tap_56g);
            CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "DFE TAP[MID]", "DC", p_dfe_tap_56g->dkit_dfe_tap_dc, "VREF", p_dfe_tap_56g->dkit_dfe_tap_vref,
            "F0", p_dfe_tap_56g->dkit_dfe_tap_f0, "F1", p_dfe_tap_56g->dkit_dfe_tap_f0, "F2", p_dfe_tap_56g->dkit_dfe_tap_f2);
            _ctc_at_dkit_get_dfe_tap(&dev, DKIT_EYE_TOP, (void*)p_dfe_tap_56g);
            CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "DFE TAP[TOP]", "DC", p_dfe_tap_56g->dkit_dfe_tap_dc, "VREF", p_dfe_tap_56g->dkit_dfe_tap_vref,
            "F0", p_dfe_tap_56g->dkit_dfe_tap_f0, "F1", p_dfe_tap_56g->dkit_dfe_tap_f0, "F2", p_dfe_tap_56g->dkit_dfe_tap_f2);
        }
        else if(CTC_DKIT_AT_SERDES_NRZ_MODE == modulation)
        {
            _ctc_at_dkit_get_dfe_tap(&dev, DKIT_EYE_MID, (void*)p_dfe_tap_56g);
            CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "DFE TAP[MID]", "DC", p_dfe_tap_56g->dkit_dfe_tap_dc, "VREF", p_dfe_tap_56g->dkit_dfe_tap_vref,
            "F0", p_dfe_tap_56g->dkit_dfe_tap_f0, "F1", p_dfe_tap_56g->dkit_dfe_tap_f0, "F2", p_dfe_tap_56g->dkit_dfe_tap_f2);
        }

        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "DFE TAP[SHARED]", "DC-E", p_dfe_tap_56g->dkit_dfe_tap_dc_e, "F1P5", p_dfe_tap_56g->dkit_dfe_tap_f1p5,
        "F3", p_dfe_tap_56g->dkit_dfe_tap_f3, "F4", p_dfe_tap_56g->dkit_dfe_tap_f4, "F5", p_dfe_tap_56g->dkit_dfe_tap_f5);
        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "DFE TAP[SHARED]", "F6", p_dfe_tap_56g->dkit_dfe_tap_f6, "F7", p_dfe_tap_56g->dkit_dfe_tap_f7,
        "F8", p_dfe_tap_56g->dkit_dfe_tap_f8, "F9", p_dfe_tap_56g->dkit_dfe_tap_f9, "F10", p_dfe_tap_56g->dkit_dfe_tap_f10);
        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "DFE TAP[SHARED]", "F11", p_dfe_tap_56g->dkit_dfe_tap_f11, "F12", p_dfe_tap_56g->dkit_dfe_tap_f12,
        "F13", p_dfe_tap_56g->dkit_dfe_tap_f13, "F14", p_dfe_tap_56g->dkit_dfe_tap_f14, "F15", p_dfe_tap_56g->dkit_dfe_tap_f15);
        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "DFE TAP[SHARED]", "FF0", p_dfe_tap_56g->dkit_dfe_tap_ff0, "FF1", p_dfe_tap_56g->dkit_dfe_tap_ff1,
        "FF2", p_dfe_tap_56g->dkit_dfe_tap_ff2, "FF3", p_dfe_tap_56g->dkit_dfe_tap_ff3, "FF4", p_dfe_tap_56g->dkit_dfe_tap_ff4, "FF5", p_dfe_tap_56g->dkit_dfe_tap_ff5);

        if(0 == dfe_freeze)
        {
            _ctc_at_dkit_set_dfe_freeze_updates(&dev, 0);
        }

        p_ffe_tap_56g = (_dkit_at_serdes_56g_ffe_tap_t*)mem_malloc(MEM_CLI_MODULE, sizeof(_dkit_at_serdes_56g_ffe_tap_t));
        if(NULL == p_ffe_tap_56g)
        {
            mem_free(p_dfe_tap_56g);
            if (p_file) { sal_fclose(p_file); }
            return CLI_ERROR;
        }
        sal_memset(p_ffe_tap_56g, 0, sizeof(_dkit_at_serdes_56g_ffe_tap_t));
        _ctc_at_dkit_get_txeq_param(&dev, (void*)p_ffe_tap_56g);  
    
        CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_file, " TX FFE config\n");
        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "FFE-PARAM", "PRE-3", p_ffe_tap_56g->tap[0],
        "PRE-2", p_ffe_tap_56g->tap[1], "PRE-1", p_ffe_tap_56g->tap[2], "MAIN", p_ffe_tap_56g->tap[3], "POST", p_ffe_tap_56g->tap[4], "NA", p_ffe_tap_56g->tap[5]);        

        p_ctle_tap_56g = (_dkit_at_serdes_56g_ctle_param_t*)mem_malloc(MEM_CLI_MODULE, sizeof(_dkit_at_serdes_56g_ctle_param_t));
        if(NULL == p_ctle_tap_56g)
        {
            mem_free(p_dfe_tap_56g);
            mem_free(p_ffe_tap_56g);
            if (p_file) { sal_fclose(p_file); }
            return CLI_ERROR;
        }
        sal_memset(p_ctle_tap_56g, 0, sizeof(_dkit_at_serdes_56g_ctle_param_t));
        _ctc_at_dkit_get_ctle_param(&dev, (void*)p_ctle_tap_56g);
        CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_file, " RX CTLE status\n");
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "CUR1_SEL  ", p_ctle_tap_56g->dkit_ctle_cur1_sel  );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "RL1_SEL   ", p_ctle_tap_56g->dkit_ctle_rl1_sel   );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "RL1_EXTRA ", p_ctle_tap_56g->dkit_ctle_rl1_extra );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "RES1_SEL  ", p_ctle_tap_56g->dkit_ctle_res1_sel  );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "CAP1_SEL  ", p_ctle_tap_56g->dkit_ctle_cap1_sel  );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "EN_MIDFREQ", p_ctle_tap_56g->dkit_ctle_en_midfreq);
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "CS1_MID   ", p_ctle_tap_56g->dkit_ctle_cs1_mid   );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "RS1_MID   ", p_ctle_tap_56g->dkit_ctle_rs1_mid   );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "CUR2_SEL  ", p_ctle_tap_56g->dkit_ctle_cur2_sel  );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "RL2_SEL   ", p_ctle_tap_56g->dkit_ctle_rl2_sel   );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "RL2_TUNE_G", p_ctle_tap_56g->dkit_ctle_rl2_tune_g);
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "RES2_SEL  ", p_ctle_tap_56g->dkit_ctle_res2_sel  );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "CAP2_SEL  ", p_ctle_tap_56g->dkit_ctle_cap2_sel  );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "CL1_SEL   ", p_ctle_tap_56g->dkit_ctle_cl1_sel   );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "CL2_SEL   ", p_ctle_tap_56g->dkit_ctle_cl2_sel   );

        mem_free(p_dfe_tap_56g);
        mem_free(p_ffe_tap_56g);
        mem_free(p_ctle_tap_56g);
    }
    else
    {
        p_dfe_tap_112g = (_dkit_at_serdes_112g_ffe_tap_param_t*)mem_malloc(MEM_CLI_MODULE, sizeof(_dkit_at_serdes_112g_ffe_tap_param_t));
        if(NULL == p_dfe_tap_112g)
        {
            if (p_file) { sal_fclose(p_file); }
            return CLI_ERROR;
        }
        sal_memset(p_dfe_tap_112g, 0, sizeof(_dkit_at_serdes_112g_ffe_tap_param_t));

        _ctc_at_dkit_get_dfe_tap(&dev, DKIT_AT112G_DATA_PATH, (void*)p_dfe_tap_112g);
        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "FFE TAP[DP]" , "PRE_6" , p_dfe_tap_112g->dkit_ffe_tap_pre_6 , "PRE_5" , p_dfe_tap_112g->dkit_ffe_tap_pre_5 ,
        "PRE_4" , p_dfe_tap_112g->dkit_ffe_tap_pre_4 , "PRE_3" , p_dfe_tap_112g->dkit_ffe_tap_pre_3 , "PRE_2" , p_dfe_tap_112g->dkit_ffe_tap_pre_2 );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "FFE TAP[DP]" , "PRE_1" , p_dfe_tap_112g->dkit_ffe_tap_pre_1 , "PST_1" , p_dfe_tap_112g->dkit_ffe_tap_pst_1 ,
        "PST_2" , p_dfe_tap_112g->dkit_ffe_tap_pst_2 , "PST_3" , p_dfe_tap_112g->dkit_ffe_tap_pst_3 , "PST_4" , p_dfe_tap_112g->dkit_ffe_tap_pst_4 );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "FFE TAP[DP]" , "PST_5" , p_dfe_tap_112g->dkit_ffe_tap_pst_5 , "PST_6" , p_dfe_tap_112g->dkit_ffe_tap_pst_6 ,
        "PST_7" , p_dfe_tap_112g->dkit_ffe_tap_pst_7 , "PST_8" , p_dfe_tap_112g->dkit_ffe_tap_pst_8 , "PST_9" , p_dfe_tap_112g->dkit_ffe_tap_pst_9 );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "FFE TAP[DP]" , "PST_10", p_dfe_tap_112g->dkit_ffe_tap_pst_10, "PST_11", p_dfe_tap_112g->dkit_ffe_tap_pst_11,
        "PST_12", p_dfe_tap_112g->dkit_ffe_tap_pst_12, "PST_13", p_dfe_tap_112g->dkit_ffe_tap_pst_13, "PST_14", p_dfe_tap_112g->dkit_ffe_tap_pst_14);
        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "FFE TAP[DP]" , "PST_15", p_dfe_tap_112g->dkit_ffe_tap_pst_15, "PST_16", p_dfe_tap_112g->dkit_ffe_tap_pst_16,
        "FLT_1" , p_dfe_tap_112g->dkit_ffe_tap_flt_1 , "FLT_2" , p_dfe_tap_112g->dkit_ffe_tap_flt_2 , "FLT_3" , p_dfe_tap_112g->dkit_ffe_tap_flt_3 );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "FFE TAP[DP]" , "FLT_4" , p_dfe_tap_112g->dkit_ffe_tap_flt_4 , "FLT_5" , p_dfe_tap_112g->dkit_ffe_tap_flt_5 ,
        "FLT_6" , p_dfe_tap_112g->dkit_ffe_tap_flt_6 , "FLT_7" , p_dfe_tap_112g->dkit_ffe_tap_flt_7 , "FLT_8" , p_dfe_tap_112g->dkit_ffe_tap_flt_8);
        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "FFE TAP[DP]" , "GAIN"  , p_dfe_tap_112g->dkit_ffe_tap_gain  , "BLW"   , p_dfe_tap_112g->dkit_ffe_tap_blw   ,
        "DFE"   , p_dfe_tap_112g->dkit_ffe_tap_dfe);

        _ctc_at_dkit_get_dfe_tap(&dev, DKIT_AT112G_CLOCK_PATH, (void*)p_dfe_tap_112g);
        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "FFE TAP[DTL]", "PRE_3" , p_dfe_tap_112g->dkit_ffe_tap_pre_3 , "PRE_2" , p_dfe_tap_112g->dkit_ffe_tap_pre_2 ,
        "PRE_1" , p_dfe_tap_112g->dkit_ffe_tap_pre_1 , "PST_1" , p_dfe_tap_112g->dkit_ffe_tap_pst_1 , "PST_2" , p_dfe_tap_112g->dkit_ffe_tap_pst_2);
        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "FFE TAP[DTL]", "PST_3" , p_dfe_tap_112g->dkit_ffe_tap_pst_3 , "GAIN"  , p_dfe_tap_112g->dkit_ffe_tap_gain  ,
        "BLW"   , p_dfe_tap_112g->dkit_ffe_tap_blw);

        p_ffe_tap_112g = (_dkit_at_serdes_112g_ffe_tap_t*)mem_malloc(MEM_CLI_MODULE, sizeof(_dkit_at_serdes_112g_ffe_tap_t));
        if(NULL == p_ffe_tap_112g)
        {
            mem_free(p_dfe_tap_112g);
            if (p_file) { sal_fclose(p_file); }
            return CLI_ERROR;
        }
        sal_memset(p_ffe_tap_112g, 0, sizeof(_dkit_at_serdes_112g_ffe_tap_t));
        _ctc_at_dkit_get_txeq_param(&dev, (void*)p_ffe_tap_112g);

        CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_file, " TX FFE config\n");
        CTC_DKITS_PRINT_FILE(p_file, " %-25s%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d%-10s:%-10d\n", "FFE-PARAM", "PRE-3", p_ffe_tap_112g->tap[0],
            "PRE-2", p_ffe_tap_112g->tap[1], "PRE-1", p_ffe_tap_112g->tap[2], "MAIN", p_ffe_tap_112g->tap[3], "POST", p_ffe_tap_112g->tap[4], "NA", p_ffe_tap_112g->tap[5]);        
        
        p_ctle_tap_112g = (_dkit_at_serdes_112g_ctle_param_t*)mem_malloc(MEM_CLI_MODULE, sizeof(_dkit_at_serdes_112g_ctle_param_t));
        if(NULL == p_ctle_tap_112g)
        {
            mem_free(p_dfe_tap_112g);
            mem_free(p_ffe_tap_112g);
            if (p_file) { sal_fclose(p_file); }
            return CLI_ERROR;
        }
        sal_memset(p_ctle_tap_112g, 0, sizeof(_dkit_at_serdes_112g_ctle_param_t));
        _ctc_at_dkit_get_ctle_param(&dev, (void*)p_ctle_tap_112g);
        CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_file, " RX CTLE status\n");
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "TRAIN_CTLE_R " , p_ctle_tap_112g->dkit_ctle_r   );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "TRAIN_CTLE_C " , p_ctle_tap_112g->dkit_ctle_c   );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "TRAIN_CTLE_GC" , p_ctle_tap_112g->dkit_ctle_gc  );
        CTC_DKITS_PRINT_FILE(p_file, " %-25s:%-10d\n", "TRAIN_CTLE_ATTEN" , p_ctle_tap_112g->dkit_ctle_atten  );
        
        mem_free(p_dfe_tap_112g);
        mem_free(p_ffe_tap_112g);
        mem_free(p_ctle_tap_112g);
    }

    if(CTC_DKIT_SERDES_RX == dump_level)
    {
        eye_data.serdes_id = psd;
        eye_data.eye_type = CTC_DKIT_SERDIS_EYE_ALL;
        eye_data.read_times = 3;
        CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_file, " EOM height & width\n");
        (void)_ctc_at_dkit_misc_serdes_eye(lchip, (void*)(&eye_data));
    }

    if((CTC_DKIT_SERDES_RX == dump_level) || (CTC_DKIT_SERDES_DETAIL == dump_level))
    {
        _ctc_at_dkit_display_training_log(&dev, p_file, NULL, 0, NULL);
    }

    if((CTC_DKIT_SERDES_RX == dump_level) || (CTC_DKIT_SERDES_DETAIL == dump_level))
    {
        CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_file, " Register Data and Pin Value\n");

        if(CTC_AT_DKIT_SERDES_56G == dev.type)
        {
            /* dump reg */
            for(reg_list_idx = 0; reg_list_idx < sizeof(at56g_reglist)/(2*sizeof(uint32));reg_list_idx++)
            {           
                for (addr = at56g_reglist[reg_list_idx][0]; addr <= at56g_reglist[reg_list_idx][1]; addr+=4)
                {
                    _ctc_at_dkit_serdes_read_reg(&dev, addr, &data);
                    CTC_DKITS_PRINT_FILE(p_file, "Read  0x%04x: 0x%08x\n", addr, data);
                }    
            }
            /* dump pin */
            for(pin_idx = 0; pin_idx < DKIT_AT56G_PIN_NUM; pin_idx++)
            {
                ctc_at_dkit_serdes_get_pin_tbl(&dev, pin_idx, &tbl_id, &fld_id);
                if(0 == tbl_id) continue;
                drv_usw_get_tbl_string_by_id(lchip, tbl_id, tbl_name);
                ptr_field_name = FIELD_NAME(lchip, tbl_id, fld_id);
                _ctc_at_dkit_serdes_get_pin(&dev, pin_idx, &val_u16);
                CTC_DKITS_PRINT_FILE(p_file, "%s(%u).%s=%u\n",tbl_name, 
                    CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(psd), ptr_field_name, val_u16);
            }
        }
        else if(CTC_AT_DKIT_SERDES_112G == dev.type)
        {
            /* dump reg */
            for(reg_list_idx = 0; reg_list_idx < sizeof(at112g_reglist)/(2*sizeof(uint32));reg_list_idx++)
            {           
                for (addr = at112g_reglist[reg_list_idx][0]; addr <= at112g_reglist[reg_list_idx][1]; addr+=4)
                {
                    _ctc_at_dkit_serdes_read_reg(&dev, addr, &data);
                    CTC_DKITS_PRINT_FILE(p_file, "Read  0x%04x: 0x%08x\n", addr, data);
                }    
            }
            /* dump pin */
            for(pin_idx = 0; pin_idx < DKIT_AT112G_PIN_NUM; pin_idx++)
            {
                ctc_at_dkit_serdes_get_pin_tbl(&dev, pin_idx, &tbl_id, &fld_id);
                if(0 == tbl_id) continue;
                drv_usw_get_tbl_string_by_id(lchip, tbl_id, tbl_name);
                ptr_field_name = FIELD_NAME(lchip, tbl_id, fld_id);
                _ctc_at_dkit_serdes_get_pin(&dev, pin_idx, &val_u16);
                CTC_DKITS_PRINT_FILE(p_file, "%s(%u).%s=%u\n",tbl_name, 
                    CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(psd), ptr_field_name, val_u16);
            }
        }
    }

    if(CTC_DKIT_SERDES_AEC_AET == dump_level)
    {
        CTC_DKITS_PRINT_FILE(p_file, " ---------------------------------------------------------------\n");
        CTC_DKITS_PRINT_FILE(p_file, " Register Data and Pin Value\n");

        /* dump reg */
        for(addr = 0; addr <= 0xffff; addr++)
        {
            _ctc_at_dkit_serdes_read_reg(&dev, addr, &data);
            CTC_DKITS_PRINT_FILE(p_file, "Read  0x%04x: 0x%08x\n", addr, data);
        }
        if(CTC_AT_DKIT_SERDES_56G == dev.type)
        {
            /* dump pin */
            for(pin_idx = 0; pin_idx < DKIT_AT56G_PIN_NUM; pin_idx++)
            {
                ctc_at_dkit_serdes_get_pin_tbl(&dev, pin_idx, &tbl_id, &fld_id);
                if(0 == tbl_id) continue;
                drv_usw_get_tbl_string_by_id(lchip, tbl_id, tbl_name);
                ptr_field_name = FIELD_NAME(lchip, tbl_id, fld_id);
                _ctc_at_dkit_serdes_get_pin(&dev, pin_idx, &val_u16);
                CTC_DKITS_PRINT_FILE(p_file, "%s(%u).%s=%u\n",tbl_name, 
                    CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(psd), ptr_field_name, val_u16);
            }
        }
        else if(CTC_AT_DKIT_SERDES_112G == dev.type)
        {
            /* dump pin */
            for(pin_idx = 0; pin_idx < DKIT_AT112G_PIN_NUM; pin_idx++)
            {
                ctc_at_dkit_serdes_get_pin_tbl(&dev, pin_idx, &tbl_id, &fld_id);
                if(0 == tbl_id) continue;
                drv_usw_get_tbl_string_by_id(lchip, tbl_id, tbl_name);
                ptr_field_name = FIELD_NAME(lchip, tbl_id, fld_id);
                _ctc_at_dkit_serdes_get_pin(&dev, pin_idx, &val_u16);
                CTC_DKITS_PRINT_FILE(p_file, "%s(%u).%s=%u\n",tbl_name, 
                    CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(psd), ptr_field_name, val_u16);
            }
        }
    }

    if (p_file)
    {
        sal_fclose(p_file);
        CTC_DKIT_PRINT("Save result to %s\n", file_name);
    }

    return CLI_SUCCESS;
}

int32
ctc_at_dkit_misc_serdes_reset(uint8 lchip, uint16 serdes_id)
{
    ctc_at_dkit_serdes_dev_t dev;
    uint16 psd;
    (void)_ctc_at_dkit_serdes_serdes_to_psd(lchip, serdes_id, &psd);

    _ctc_at_dkit_serdes_dev(lchip, psd, &dev);
    _ctc_at_dkit_serdes_reset(&dev, DKIT_AT_TXRX_RESET, 1);
    _ctc_at_dkit_serdes_reset(&dev, DKIT_AT_TXRX_RESET, 0);

    return CLI_SUCCESS;    
}

STATIC int32
_ctc_at_dkit_misc_serdes_loopback(uint8 lchip, void *p_data)
{
    CTC_DKIT_PRINT(" Feature not support!\n");    
    return CLI_SUCCESS;    
}

#define __FIRMWARE__
#if 0
STATIC int32
_ctc_at_dkit_misc_serdes_get_fw_status(ctc_at_dkit_serdes_dev_t* p_dev)
{
    /*
    uint16 data = 0;
    uint8 load_stat = 0;
    uint8 running_stat = 0;
    uint16 val_0 = 0, val_1 = 0;
    */

    /*Load Status*/
    

    /*Running Status. check the watchdog counter to see if FW is incrementing it*/
    
    /*
    CTC_DKIT_PRINT("---------SerDes %d FirmWare Status---------\n", serdes_id);
    CTC_DKIT_PRINT("%-20s : %10s\n","Load Status", (load_stat ? "Success" : "FAILURE"));
    CTC_DKIT_PRINT("%-20s : %10s\n","Running Status", (running_stat ? "Normal" : "Abnormal"));
    CTC_DKIT_PRINT("------------------------------------------\n");
    */

    return CLI_SUCCESS;    
}

STATIC int32
_ctc_at_dkit_misc_serdes_fw(uint8 lchip, void *p_data)
{
    ctc_dkit_at_serdes_ctl_fw_t *p_fw;
    ctc_at_dkit_serdes_dev_t dev;

    p_fw = (ctc_dkit_at_serdes_ctl_fw_t *)p_data;
    _ctc_at_dkit_serdes_dev(lchip, p_fw->serdes_id, &dev);
    
    switch(p_fw->oper)
    {
        case 0:
            /*GET FW_RUNNING STAUS*/
            //_ctc_tmm_dkit_msic_serdes_get_fw_status(lchip, serdes_id);
            break;
        case 2:
            /*Unload Firmware*/
            //_ctc_tmm_dkit_msic_serdes_fw_unload(lchip, serdes_id);
            break;
        default :
            CTC_DKIT_PRINT("Feature not supported!\n");
            break;
    }

    return CLI_SUCCESS;    
}
#endif
uint32 ctc_at_dkit_get_macgroup_valid(uint8 lchip, uint8 core_id)
{
    uint8  chip_type = _ctc_at_dkit_get_chip_type(lchip);
    uint32 mac_group_valid = 0;

    uint32 mac_group_dcm_ag[CTC_DKIT_AT_CORE_NUM]      = {0x3fffc, 0x3fffc};
    uint32 mac_group_scm_ag_full[CTC_DKIT_AT_CORE_NUM] = {0xfffff, 0};
    //uint32 mac_group_scm_ag[CTC_DKIT_AT_CORE_NUM]      = {0x3fffc, 0};
    uint32 mac_group_scm_pg[CTC_DKIT_AT_CORE_NUM]      = {0x7fffe, 0};
    uint32 mac_group_dcm_pg[CTC_DKIT_AT_CORE_NUM]      = {0x3fffc, 0x3fffc};

    switch (chip_type)
    {
        case CTC_DKIT_AT_SUBTYPE_1:
            mac_group_valid = mac_group_scm_ag_full[core_id];
            break;
        case CTC_DKIT_AT_SUBTYPE_2:
            mac_group_valid = mac_group_scm_pg[core_id];
            break;
        case CTC_DKIT_AT_SUBTYPE_3:
            mac_group_valid = mac_group_dcm_ag[core_id];
            break;
        case CTC_DKIT_AT_SUBTYPE_4:
            mac_group_valid = mac_group_dcm_pg[core_id];
            break;
        default:
            break;
    }

    return mac_group_valid;   
}

void ctc_at_dkit_macpcs_clear_abnormal_interrupt(uint8 lchip, uint8 core_id, uint8 inst, uint32 tbl_id)
{
    uint32 index;
    uint32 cmd;
    uint32 fld_id;
    uint32 value;
    ds_t   ds;
    
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    index  = DRV_INS(inst, 1);
    value  = 1;
    for(fld_id = 0; fld_id < TABLE_FIELD_NUM(lchip, tbl_id); fld_id++)
    {
        DRV_IOW_FIELD(lchip, tbl_id, fld_id, &value, (void*)&ds);
    }
    (void) DRV_IOCTL_BMP(lchip, index, DKIT_DRV_CMD_BMP(cmd, DKIT_DRV_IO_CORE_BMP(core_id)), &ds);
   
}
void ctc_at_dkit_macpcs_mask_abnormal_interrupt(uint8 lchip, uint8 core_id, uint8 inst, uint32 tbl_id, uint8 mask)
{
    uint32 index;
    uint32 cmd;
    uint32 fld_id;
    uint32 value;
    ds_t   ds;
    
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);

    if(mask == 0)
    {
        index = DRV_INS(inst, 3);
    }
    else
    {
        index = DRV_INS(inst, 2);
    }
    
    value = 1;

    for(fld_id = 0; fld_id < TABLE_FIELD_NUM(lchip, tbl_id); fld_id++)
    {
        DRV_IOW_FIELD(lchip, tbl_id, fld_id, &value, (void*)&ds);
    }
    (void) DRV_IOCTL_BMP(lchip, index, DKIT_DRV_CMD_BMP(cmd, DKIT_DRV_IO_CORE_BMP(core_id)), &ds);
}
void ctc_at_dkit_macpcs_show_abnormal_interrupt(uint8 lchip, uint8 core_id, uint8 inst, uint32 tbl_id)
{
    uint32 value;
    uint32 index;
    uint32 cmd;
    uint32 fld_id;
    ds_t   ds;

    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    index  = DRV_INS(inst, 0);
    (void) DRV_IOCTL_BMP(lchip, index, DKIT_DRV_CMD_BMP(cmd, DKIT_DRV_IO_CORE_BMP(core_id)), &ds);  

    for(fld_id = 0; fld_id < TABLE_FIELD_NUM(lchip, tbl_id); fld_id++)
    {
        DRV_IOR_FIELD(lchip, tbl_id, fld_id, &value, &ds);
        if(0 != value)
        {
            CTC_DKIT_PRINT("%-7s%-5d %-7d %-12d %-30s %-30s %d\n"," ", lchip, core_id, inst, TABLE_NAME(lchip, tbl_id), FIELD_NAME(lchip,tbl_id,fld_id),value);
        }
    }

}

void ctc_at_dkit_macpcs_abnormal_interrupt(uint8 lchip, uint8 op)
{
    uint8   core_id;
    uint8   core_num = 0;
    uint8   mask = 0;
    uint8   mac_group_id;
    uint32  mac_group_valid;

    /*TODO : get core num */
    core_num = (_ctc_at_dkit_chip_is_dc(lchip)) ? 2 : 1;
    
    if(3 == op)
    {
        CTC_DKIT_PRINT("###### %-5s %-7s %-12s %-30s %-30s %s######\n", "lchip", "core_id", "inst", "table name", "field name", "value");
    }

    if(1 == op)
    {
        mask = 1;
    }
    else if(2 == op)
    {
        mask = 0;
    }

    for(core_id = 0; core_id < core_num; core_id++)
    {
        mac_group_valid = ctc_at_dkit_get_macgroup_valid(lchip, core_id);    
        for(mac_group_id = 0; mac_group_id < DKIT_AT_MCMAC_NUM_PER_CORE; mac_group_id++)
        {
            /*TODO : skip invalid mac group */
            if(!DKITS_IS_BIT_SET(mac_group_valid,mac_group_id))
            {
                continue;
            }
            
            if(0 == op)
            {
                ctc_at_dkit_macpcs_clear_abnormal_interrupt(lchip, core_id, mac_group_id, McMacInterruptNormal_t);
                ctc_at_dkit_macpcs_clear_abnormal_interrupt(lchip, core_id, mac_group_id, CtcMacCtlInterruptFunc_t);
                ctc_at_dkit_macpcs_clear_abnormal_interrupt(lchip, core_id, mac_group_id, McPcs800InterruptNormal_t);
                ctc_at_dkit_macpcs_clear_abnormal_interrupt(lchip, core_id, mac_group_id*2, McPcs400InterruptNormal_t);
                ctc_at_dkit_macpcs_clear_abnormal_interrupt(lchip, core_id, mac_group_id*2+1, McPcs400InterruptNormal_t);
                ctc_at_dkit_macpcs_clear_abnormal_interrupt(lchip, core_id, mac_group_id*2, CtcHsCtlInterruptFunc_t);
                ctc_at_dkit_macpcs_clear_abnormal_interrupt(lchip, core_id, mac_group_id*2+1, CtcHsCtlInterruptFunc_t);               
                ctc_at_dkit_macpcs_clear_abnormal_interrupt(lchip, core_id, mac_group_id*2, CtcHsCtlInterruptNormal_t);
                ctc_at_dkit_macpcs_clear_abnormal_interrupt(lchip, core_id, mac_group_id*2+1, CtcHsCtlInterruptNormal_t);
            }
            else if(1 == op || 2 == op)
            {
                ctc_at_dkit_macpcs_mask_abnormal_interrupt(lchip, core_id, mac_group_id, McMacInterruptNormal_t,mask);
                ctc_at_dkit_macpcs_mask_abnormal_interrupt(lchip, core_id, mac_group_id, CtcMacCtlInterruptFunc_t,mask);
                ctc_at_dkit_macpcs_mask_abnormal_interrupt(lchip, core_id, mac_group_id, McPcs800InterruptNormal_t,mask);
                ctc_at_dkit_macpcs_mask_abnormal_interrupt(lchip, core_id, mac_group_id*2, McPcs400InterruptNormal_t,mask);
                ctc_at_dkit_macpcs_mask_abnormal_interrupt(lchip, core_id, mac_group_id*2+1, McPcs400InterruptNormal_t,mask);
                ctc_at_dkit_macpcs_mask_abnormal_interrupt(lchip, core_id, mac_group_id*2, CtcHsCtlInterruptFunc_t,mask);
                ctc_at_dkit_macpcs_mask_abnormal_interrupt(lchip, core_id, mac_group_id*2+1, CtcHsCtlInterruptFunc_t,mask);               
                ctc_at_dkit_macpcs_mask_abnormal_interrupt(lchip, core_id, mac_group_id*2, CtcHsCtlInterruptNormal_t,mask);
                ctc_at_dkit_macpcs_mask_abnormal_interrupt(lchip, core_id, mac_group_id*2+1, CtcHsCtlInterruptNormal_t,mask);
            }
            else if(3 == op)
            {                  
                ctc_at_dkit_macpcs_show_abnormal_interrupt(lchip, core_id, mac_group_id, McPcs800InterruptNormal_t);
                ctc_at_dkit_macpcs_show_abnormal_interrupt(lchip, core_id, mac_group_id, CtcMacCtlInterruptFunc_t);
                ctc_at_dkit_macpcs_show_abnormal_interrupt(lchip, core_id, mac_group_id, McMacInterruptNormal_t);
                ctc_at_dkit_macpcs_show_abnormal_interrupt(lchip, core_id, mac_group_id*2, McPcs400InterruptNormal_t);
                ctc_at_dkit_macpcs_show_abnormal_interrupt(lchip, core_id, mac_group_id*2+1, McPcs400InterruptNormal_t);
                ctc_at_dkit_macpcs_show_abnormal_interrupt(lchip, core_id, mac_group_id*2, CtcHsCtlInterruptFunc_t);
                ctc_at_dkit_macpcs_show_abnormal_interrupt(lchip, core_id, mac_group_id*2+1, CtcHsCtlInterruptFunc_t);  
                ctc_at_dkit_macpcs_show_abnormal_interrupt(lchip, core_id, mac_group_id*2, CtcHsCtlInterruptNormal_t);
                ctc_at_dkit_macpcs_show_abnormal_interrupt(lchip, core_id, mac_group_id*2+1, CtcHsCtlInterruptNormal_t);
            }
            else
            {
                CTC_DKIT_PRINT("%s\n","invalid op");
                return;
            }
        }
    }
}

void
_ctc_at_dkit_misc_serdes_print_mcu_cmd_guide()
{
    CTC_DKIT_PRINT("Commands Description\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PARAMETER   PIN NAME                       DESCRIPTION\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("IN PARA[1]  PIN_MCU_REMOTE_COMMAND[31:24]  Command type decoding. See Table below for command types\n");
    CTC_DKIT_PRINT("IN PARA[2]  PIN_MCU_REMOTE_COMMAND[23:16]  Sub-category decoding bits of each command type\n");
    CTC_DKIT_PRINT("IN PARA[3]  PIN_MCU_REMOTE_COMMAND[15:8]   Command number that increases sequentially\n");
    CTC_DKIT_PRINT("IN PARA[4]  PIN_MCU_REMOTE_COMMAND[7:0]    Control bits, that is min/max value, read/write, and more\n");
    CTC_DKIT_PRINT("IN PARA[5]  PIN_MCU_REMOTE_STATUS          Includes input data of the corresponding command into the HS\n");
    CTC_DKIT_PRINT("OUT         PIN_MCU_LOCAL_STATUS           Includes output data returned from the COMPHY\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("\n");
    CTC_DKIT_PRINT("Command Type Decoding\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command Type           COMMAND[31:24]  Description\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Training protocol      0x0             KR training, Tx equalizer control\n");
    CTC_DKIT_PRINT("Receiver equalization  0x1             CTLE setting\n");
    CTC_DKIT_PRINT("Register access        0x2             Register read and write\n");
    CTC_DKIT_PRINT("Data path control      0x3             Data path control\n");
    CTC_DKIT_PRINT("PCIe PIPE              0x4             Lane margin setting\n");
    CTC_DKIT_PRINT("Analog calibration     0x5             Analog calibration setting\n");
    CTC_DKIT_PRINT("Power/Speed control    0x6             Only support SerDes mode power on/off, speed change, soft reset \n");
    CTC_DKIT_PRINT("SAS APTA               0x7             Only support SAS mode APTA control\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("\n");
    CTC_DKIT_PRINT("0x0 Training Protocol Commands\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Tx Equalizer Control  Description\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[31:24] 0x0\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x1\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  [15:14]               Not used\n");
    CTC_DKIT_PRINT("                              [31:8]                em_pre2_ctrl (C1)\n");
    CTC_DKIT_PRINT("                              [7:6]                 Not used\n");
    CTC_DKIT_PRINT("                              [5:0]                 em_pre_ctrl (C2)\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_STATUS[15:0]   [15:14]               Not used\n");
    CTC_DKIT_PRINT("                              [13:8]                em_main_ctrl (C3)\n");
    CTC_DKIT_PRINT("                              [7:6]                 Not used\n");
    CTC_DKIT_PRINT("                              [5:0]                 em_post_ctrl (C4)\n");
    CTC_DKIT_PRINT("PIN_MCU_LOCAL_STATUS[31:0]    [31:30]               Not used\n");
    CTC_DKIT_PRINT("                              [29:24]               em_pre2_ctr (C1)\n");
    CTC_DKIT_PRINT("                              [23:22]               Not used\n");
    CTC_DKIT_PRINT("                              [21:16]               em_pre_ctrl (C2)\n");
    CTC_DKIT_PRINT("                              [15:14]               Not used\n");
    CTC_DKIT_PRINT("                              [13:8]                em_main_ctrl (C3)\n");
    CTC_DKIT_PRINT("                              [7:6]                 Not used\n");
    CTC_DKIT_PRINT("                              [5:0]                 em_post_ctrl (C4)\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Tx Training           Description\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x2                   This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x0\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]                 Reserved\n");
    CTC_DKIT_PRINT("PIN_MCU_LOCAL_STATUS[15:0]    [0]                   Tx training failed\n");
    CTC_DKIT_PRINT("                                                    0x0: Training was successful (default)\n");
    CTC_DKIT_PRINT("                                                    0x1: Training failed\n");
    CTC_DKIT_PRINT("                              [2:1]                 Tx training error\n");
    CTC_DKIT_PRINT("                              [15:3]                Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("\n");
    CTC_DKIT_PRINT("0x1 Receiver Equalization Commands\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Rx Initialization     Description\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x2                   This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x0                   \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]                 Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Rx Training           Description\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x2                   This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x1\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]                 Reserved\n");
    CTC_DKIT_PRINT("PIN_MCU_LOCAL_STATUS[15:0]    [0]                   Rx training failed\n");
    CTC_DKIT_PRINT("                                                    0x0: Training was successful (default)\n");
    CTC_DKIT_PRINT("                                                    0x1: Training failed\n");
    CTC_DKIT_PRINT("                              [15:1]                Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("\n");
    CTC_DKIT_PRINT("0x2 Register Access Commands\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Register Addr Select  Description\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x0\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]                 Reserved\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_STATUS[15:0]   [15:0]                Register address\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Register Write        Description                  \n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0                   \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x1                   \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]                 Reserved\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_STATUS[15:0]   [7:0]                 Write data\n");
    CTC_DKIT_PRINT("                              [15:8]                Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Register Mask Write   Description\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x2\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]                 Reserved\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_STATUS[15:0]   [7:0]                 Mask each bit of the write data\n");
    CTC_DKIT_PRINT("                                                    0x0: Mask, register value is unchanged\n");
    CTC_DKIT_PRINT("                                                    0x1: No mask, the provided value is written to register\n");
    CTC_DKIT_PRINT("                              [15:8]                Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Register Read         Description\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0                   \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x3                   \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]                 Reserved\n");
    CTC_DKIT_PRINT("PIN_MCU_LOCAL_STATUS[15:0]    [7:0]                 Read data\n");
    CTC_DKIT_PRINT("                              [15:8]                Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("\n");
    CTC_DKIT_PRINT("0x3 Data Path Control Commands\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Datapath Control          Description\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0                       \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x0                       Tx polarity\n");
    CTC_DKIT_PRINT("                              0x1                       Tx gray encode\n");
    CTC_DKIT_PRINT("                              0x2                       Tx precode\n");
    CTC_DKIT_PRINT("                              0x3                       Tx swizzle (MSb/LSb swap)\n");
    CTC_DKIT_PRINT("                              0x4                       Rx polarity\n");
    CTC_DKIT_PRINT("                              0x5                       Rx gray decode\n");
    CTC_DKIT_PRINT("                              0x6                       Rx precode decode\n");
    CTC_DKIT_PRINT("                              0x7                       Rx swizzle (MSb/LSb swap)\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [0]                       0x0: Off\n");
    CTC_DKIT_PRINT("                                                        0x1: On\n");
    CTC_DKIT_PRINT("                              [7:1]                     Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Rx Deterministic Latency  Description\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x1\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x0\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]                     Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("\n");
    CTC_DKIT_PRINT("0x6 Power/Speed Control Commands\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Power on Tx      Description\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0              This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x0              \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]            Reserved\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:0]  [7:0]            PHY_GEN_TX value\n");
    CTC_DKIT_PRINT("                              [15:8]           Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Power on Rx      Description            \n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0              This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x1              \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]            Reserved\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:0]  [7:0]            PHY_GEN_RX value\n");
    CTC_DKIT_PRINT("                              [15:8]           Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Power on TRx     Description           \n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0              This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x2              \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]            Reserved\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:0]  [7:0]            PHY_GEN_TX and PHY_GEN_RX value\n");
    CTC_DKIT_PRINT("                              [15:8]           Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Power off Tx     Description           \n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0              This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x3              \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]            Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Power off Rx     Description           \n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0              This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x4              \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]            Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Power off TRx     Description          \n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0              This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x5              \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]            Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Speed Change Tx  Description       \n");
    CTC_DKIT_PRINT("----------------------------------------------------------------------------------------------------------- \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0              This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x6              \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]            Reserved\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:0]  [7:0]            PHY_GEN_TX value\n");
    CTC_DKIT_PRINT("                              [15:8]           Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Speed Change Rx  Description            \n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0              This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x7              \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]            Reserved\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:0]  [7:0]            PHY_GEN_RX value\n");
    CTC_DKIT_PRINT("                              [15:8]           Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("Command                       Speed Change TRx Description           \n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0              This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x8              \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]            Reserved\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:0]  [7:0]            PHY_GEN_TX and PHY_GEN_RX value\n");
    CTC_DKIT_PRINT("                              [15:8]           Reserved\n");
    CTC_DKIT_PRINT("Command                       Soft Reset Tx    Description              \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0              This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0x9              \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]            Reserved\n");
    CTC_DKIT_PRINT("Command                       Soft Reset Rx    Description              \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0              This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0xA              \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]            Reserved\n");
    CTC_DKIT_PRINT("Command                       Soft Reset TRx   Description             \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[23:16] 0x0              This command is for testing purpose and not used for SoC\n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[15:8]  0xB              \n");
    CTC_DKIT_PRINT("PIN_MCU_REMOTE_COMMAND[7:0]   [7:0]            Reserved\n");
    CTC_DKIT_PRINT("-----------------------------------------------------------------------------------------------------------\n");
}

void
_ctc_at_dkit_misc_serdes_mcu_cmd(ctc_at_dkit_serdes_dev_t* p_dev, 
    uint8 cmd_0to7, uint8 cmd_8to15, uint8 cmd_16to23, uint8 cmd_24to31, uint32 rmt_stat)
{
    uint8  grp_id = CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(p_dev->serdes_id);
    uint8  ins    = CTC_DKIT_AT_IS_CPUMAC_SERDES(p_dev->serdes_id) ? 0 : grp_id;
    uint8  core   = CTC_DKIT_AT_GET_CORE_ID_BY_LOGIC_SERDES(p_dev->serdes_id);
    uint8  lane   = p_dev->serdes_id % 4;
    uint32 tbl_id = 0;
    uint32 fld_id = 0;
    uint32 tbl_id_mon = 0;
    uint32 fld_id_mon = 0;
    uint32 index  = DRV_INS(ins, 0);
    uint32 cmd    = 0;
    uint32 times = 300; /*at most 3s*/
    uint32 val[9] = {0};
    uint32 val_mon = 0;
    uint32 val_tmp = 0;
    uint32 val32  = ((uint32)cmd_0to7) | (((uint32)cmd_8to15) << 8) | (((uint32)cmd_16to23) << 16) | (((uint32)cmd_24to31) << 24);

    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        if(CTC_DKIT_AT_IS_CPUMAC_SERDES(p_dev->serdes_id))
        {
            tbl_id = CpuMacHssMcuCmdCfg_t;
            tbl_id_mon = CpuMacHssMcuCmdMon_t;
        }
        else
        {
            tbl_id = HssMcuCmdCfg_t;
            tbl_id_mon = HssMcuCmdMon_t;
        }
    }
    else
    {
        tbl_id = HssMcuCmdCfg_t;
        tbl_id_mon = HssMcuCmdMon_t;
    }

    /*0. check PIN_MCU_LOCAL_ACK 0*/
    cmd = DRV_IOR(tbl_id_mon, DRV_ENTRY_FLAG);
    (void)(DKIT_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));
    fld_id_mon = HssMcuCmdMon_monHssMcuLocalAckLane0_f+lane;
    DRV_IOR_FIELD(p_dev->lchip, tbl_id_mon, fld_id_mon, &val_mon, val);
    if(0 != val_mon)
    {
        CTC_DKIT_PRINT("Aborted, previous MCU CMD is still running!\n");
        return;
    }

    /*1. Set PIN_MCU_REMOTE_COMMAND and PIN_MCU_REMOTE_STATUS.*/
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    (void)(DKIT_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));
    
    fld_id = HssMcuCmdCfg_cfgHssMcuRemoteCommandLane0_f+lane;
    DKIT_DRV_IOW_FIELD_NZ(core, 0xff, 0xff, p_dev->lchip, tbl_id, ins, fld_id, &val32, val);
    
    fld_id = HssMcuCmdCfg_cfgHssMcuRemoteStatusLane0_f+lane;
    DKIT_DRV_IOW_FIELD_NZ(core, 0xff, 0xff, p_dev->lchip, tbl_id, ins, fld_id, &rmt_stat, val);
    
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    (void)(DKIT_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));
    
    /*2. To initiate a command, set PIN_MCU_REMOTE_REQ = 0x1.*/
    val_tmp = 1;
    fld_id = HssMcuCmdCfg_cfgHssMcuRemoteReqLane0_f+lane;
    DKIT_DRV_IOW_FIELD_NZ(core, 0xff, 0xff, p_dev->lchip, tbl_id, ins, fld_id, &val_tmp, val);
    
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    (void)(DKIT_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));
    
    /*3. The COMPHY receives the command, processes it, and sets PIN_MCU_LOCAL_ACK = 0x1.*/
    cmd = DRV_IOR(tbl_id_mon, DRV_ENTRY_FLAG);
    while(--times)
    {
        (void)(DKIT_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));
        DRV_IOR_FIELD(p_dev->lchip, tbl_id_mon, fld_id_mon, &val_mon, val);
        if(1 == val_mon)
        {
            break;
        }
        sal_task_sleep(10);
    }
    if(0 == val_mon)
    {
        CTC_DKIT_PRINT("Aborted, cannot get valid LOCAL ACK!\n");
    }
    
    /*4. Once PIN_MCU_LOCAL_ACK = 0x1, the command status is valid on PIN_MCU_LOCAL_STATUS.*/
    fld_id_mon = HssMcuCmdMon_monHssMcuLocalStatusLane0_f+lane;
    DRV_IOR_FIELD(p_dev->lchip, tbl_id_mon, fld_id_mon, &val_mon, val);
    CTC_DKIT_PRINT("LOCAL_STATUS: 0x%08x\n", val_mon);
    
    /*5. After the rising edge of PIN_MCU_LOCAL_ACK, set PIN_MCU_REMOTE_REQ = 0x0.*/
    /*6. PIN_MCU_LOCAL_ACK is set = 0x0 by the COMPHY.*/
    /*7. After the falling edge of PIN_MCU_LOCAL_ACK, the COMPHY is ready to accept the next command.*/
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    (void)(DKIT_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));

    val_tmp = 0;
    fld_id = HssMcuCmdCfg_cfgHssMcuRemoteReqLane0_f+lane;
    DKIT_DRV_IOW_FIELD_NZ(core, 0xff, 0xff, p_dev->lchip, tbl_id, ins, fld_id, &val_tmp, val);
    
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    (void)(DKIT_DRV_IOCTL_CORE(p_dev->lchip, index, core, cmd, val));
}

void
_ctc_at_dkit_misc_serdes_tx_err_inj(ctc_at_dkit_serdes_dev_t* p_dev, uint8 errors)
{
    uint32 err_num = 0;
    
    if(0 == errors) return;
    
    err_num = (errors >= 8) ? 7 : (errors-1);
    
    if(CTC_AT_DKIT_SERDES_56G == p_dev->type)
    {
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ADD_ERR_NUM), 
            CTC_AT_DKIT_SERDES_REG_LANE, err_num);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ADD_ERR_EN), 
            CTC_AT_DKIT_SERDES_REG_LANE, 0);
        sal_task_sleep(5);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ADD_ERR_EN), 
            CTC_AT_DKIT_SERDES_REG_LANE, 1);
        sal_task_sleep(5);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT56G_ADD_ERR_EN), 
            CTC_AT_DKIT_SERDES_REG_LANE, 0);
    }
    else if(CTC_AT_DKIT_SERDES_112G == p_dev->type)
    {
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ADD_ERR_NUM), 
            CTC_AT_DKIT_SERDES_REG_LANE, err_num);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ADD_ERR_EN), 
            CTC_AT_DKIT_SERDES_REG_LANE, 0);
        sal_task_sleep(5);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ADD_ERR_EN), 
            CTC_AT_DKIT_SERDES_REG_LANE, 1);
        sal_task_sleep(5);
        _ctc_at_dkit_serdes_write_reg_field(p_dev, DKIT_REG_STR(F_DKIT_AT112G_ADD_ERR_EN), 
            CTC_AT_DKIT_SERDES_REG_LANE, 0);
    }
}

void
_ctc_at_dkit_misc_serdes_abnormal_intr_clear(uint8 lchip, uint16 serdes_id)
{
    uint8  grp_id    = CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(serdes_id);
    uint8  ins       = CTC_DKIT_AT_IS_CPUMAC_SERDES(serdes_id) ? 0 : grp_id;
    uint8  core      = CTC_DKIT_AT_GET_CORE_ID_BY_LOGIC_SERDES(serdes_id);
    uint8  lane      = serdes_id % 4;
    uint32 tbl_id    = 0;
    uint32 index     = 0;
    uint32 cmd       = 0;
    uint32 val_lane0 = 0x02222210;
    uint32 val_cmn   = 0x04000021;
    uint32 value     = (val_lane0 >> lane) | val_cmn;

    if(CTC_DKIT_AT_IS_CPUMAC_SERDES(serdes_id))
    {
        tbl_id = CpuMacProcInterruptNormal_t;
    }
    else
    {
        tbl_id = CtcHsCtlInterruptNormal_t;
    }
    /*mask interrupt*/
    index  = DRV_INS(ins, 2);
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    (void)(DKIT_DRV_IOCTL_CORE(lchip, index, core, cmd, &value));
    /*clear interrupt*/
    index  = DRV_INS(ins, 1);
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    (void)(DKIT_DRV_IOCTL_CORE(lchip, index, core, cmd, &value));
}

void
_ctc_at_dkit_misc_serdes_abnormal_intr_test(uint8 lchip, uint16 serdes_id)
{
    uint8  grp_id    = CTC_DKIT_AT_SERDES_GET_GROUP_PER_CORE(serdes_id);
    uint8  ins       = CTC_DKIT_AT_IS_CPUMAC_SERDES(serdes_id) ? 0 : grp_id;
    uint8  core      = CTC_DKIT_AT_GET_CORE_ID_BY_LOGIC_SERDES(serdes_id);
    uint8  lane      = serdes_id % 4;
    uint32 tbl_id    = 0;
    uint32 index     = 0;
    uint32 cmd       = 0;
    uint32 val_lane0 = 0x02222210;
    uint32 val_cmn   = 0x04000021;
    uint32 value     = (val_lane0 >> lane) | val_cmn;
    uint32 val_tmp   = 0;

    if(CTC_DKIT_AT_IS_CPUMAC_SERDES(serdes_id))
    {
        tbl_id = CpuMacProcInterruptNormal_t;
    }
    else
    {
        tbl_id = CtcHsCtlInterruptNormal_t;
    }
    /*read interrupt*/
    index  = DRV_INS(ins, 0);
    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    (void)(DKIT_DRV_IOCTL_CORE(lchip, index, core, cmd, &val_tmp));

    if((val_tmp & value) == value)
    {
        if((val_tmp & 0x00000001) == 0x00000001)
        {
            CTC_DKIT_PRINT("intHssMemEccErrorCmnMcu 1\n");
        }
        if((val_tmp & 0x00000020) == 0x00000020)
        {
            CTC_DKIT_PRINT("intPramEccErrorMcu 1\n");
        }
        if((val_tmp & 0x04000000) == 0x04000000)
        {
            CTC_DKIT_PRINT("intHssMcuWdtCmnMcu 1\n");
        }
        if((val_tmp & 0x0000001e) != 0)
        {
            CTC_DKIT_PRINT("intHssMemEccErrorLane%uMcu 1\n", lane);
        }
        if((val_tmp & 0x000003c0) != 0)
        {
            CTC_DKIT_PRINT("intrTxAsyncFifoUnderrunLane%uMcu 1\n", lane);
        }
        if((val_tmp & 0x00003c00) != 0)
        {
            CTC_DKIT_PRINT("intrTxAsyncFifoOverrunLane%uMcu 1\n", lane);
        }
        if((val_tmp & 0x0003c000) != 0)
        {
            CTC_DKIT_PRINT("intrRxAsyncFifoOverrunLane%uMcu 1\n", lane);
        }
        if((val_tmp & 0x003c0000) != 0)
        {
            CTC_DKIT_PRINT("anethInterruptNormalLane%uMcu 1\n", lane);
        }
        if((val_tmp & 0x03c00000) != 0)
        {
            CTC_DKIT_PRINT("intHssMcuWdtLane%uMcu 1\n", lane);
        }
    }
}

int32
_ctc_at_dkit_misc_serdes_rx_prbs_run(ctc_at_dkit_serdes_dev_t* p_dev, uint32 new_pattern)
{
    uint32 cur_en;
    uint32 pattern;
    uint16 en = 0;
    uint16 co = 0;
    uint16 fa = 0;
    uint16 serdes_id = 0;
    uint32 gap_ms = 100;
    uint32 times = 30;
    uint32 ret;
    ctc_at_dkit_serdes_dev_t dev;
    ctc_dkit_monitor_task_t* p_mon_task = &(g_usw_dkit_master[p_dev->lchip]->monitor_task[CTC_DKIT_MONITOR_TASK_PRBS_BER]);
    ctc_dkit_at_serdes_ber_mon_t* p_ber_mon = NULL;
    char thread_name[SAL_TASK_MAX_NAME_LEN] = {0};
    char* pattern_name[] = {"PRBS7", "PRBS7", "PRBS15", "PRBS15", "PRBS23", "PRBS23", "PRBS31", "PRBS31", "PRBS9", "Squareware(8081)", "PRBS11", "PRBS1T(1010)",
                        "PRBS13", "PRBS9", "PRBS13", "PRBS15", "PRBS31", "PRBS9", "PRBS13", "PRBS15", "PRBS31"};

    _ctc_at_dkit_serdes_dev(p_dev->lchip, p_dev->serdes_id, &dev);

    _ctc_at_dkit_misc_serdes_opr_lock(p_dev->lchip, p_dev->serdes_id);

    /* 1. set rx prbs pattern & enable stats*/
    _ctc_at_dkit_get_prbs_pattern(&dev, DKIT_AT_DIR_RX, &pattern);
    if(pattern != new_pattern)
    {
        _ctc_at_dkit_set_prbs_pattern(&dev, DKIT_AT_DIR_RX, new_pattern);
    }
    _ctc_at_dkit_get_prbs_en(&dev, DKIT_AT_DIR_RX, &cur_en);
    if(!cur_en)
    {
        _ctc_at_dkit_set_prbs_en(&dev, DKIT_AT_DIR_RX, 1);
        /*wait previous tx || rx train done*/
        while(times--)
        {
            _ctc_at_dkit_misc_serdes_get_rx_train_stat(&dev, &en, &co, &fa);
            if((!en) || (en && co))
            {
                break;
            }
            sal_task_sleep(gap_ms);
        }
        times = 30;
        while(times--)
        {
            _ctc_at_dkit_misc_serdes_get_tx_train_stat(&dev, &en, &co, &fa);
            if((!en) || (en && co))
            {
                break;
            }
            sal_task_sleep(gap_ms);
        }
        _ctc_at_dkit_reset_comparator_stats(&dev);
        _ctc_at_dkit_misc_serdes_ber_record_clear(p_dev->lchip, p_dev->serdes_id);
    }
    /*2. run thread*/
    if(NULL == p_mon_task->monitor_task)
    {
        if(NULL == p_mon_task->para)
        {
            p_ber_mon = (ctc_dkit_at_serdes_ber_mon_t*)mem_malloc(MEM_CLI_MODULE, 
                sizeof(ctc_dkit_at_serdes_ber_mon_t));
            if(NULL == p_ber_mon)
            {
                return CLI_ERROR;
            }
            sal_memset(p_ber_mon, 0, sizeof(ctc_dkit_at_serdes_ber_mon_t));
            p_ber_mon->lchip = p_dev->lchip;
            sal_memset(p_ber_mon->opr_lock, 0, sizeof(uint8)*DKIT_SERDES_ID_MAX);
            sal_memset(p_ber_mon->is_mon, 0, sizeof(uint8)*DKIT_SERDES_ID_MAX);
            sal_memset(p_ber_mon->tot_cnt, 0, sizeof(uint64)*DKIT_SERDES_ID_MAX);
            sal_memset(p_ber_mon->err_cnt, 0, sizeof(uint64)*DKIT_SERDES_ID_MAX);
            p_mon_task->para = (void*)p_ber_mon;
        }
        p_mon_task->task_end = 0;
        sal_sprintf(thread_name, "AT-Serdes-PRBS-BER-MON-%d", p_dev->lchip);
        ret = sal_task_create(&p_mon_task->monitor_task,
                            thread_name,
                            SAL_DEF_TASK_STACK_SIZE,
                            SAL_TASK_PRIO_DEF,
                            _ctc_at_dkit_misc_serdes_monitor_prbs_stat_handler,
                            p_mon_task->para);
        if(CLI_ERROR == ret)
        {
            return CLI_ERROR;
        }
    }
    _ctc_at_dkit_misc_serdes_ber_record_start(p_dev->lchip, p_dev->serdes_id);

    _ctc_at_dkit_misc_serdes_opr_unlock(p_dev->lchip, p_dev->serdes_id);

    _ctc_at_dkit_serdes_psd_to_serdes(p_dev->lchip, p_dev->serdes_id, &serdes_id);
    CTC_DKIT_PRINT("Serdes %u PRBS test start, %s\n", serdes_id, pattern_name[new_pattern]);

    return CLI_SUCCESS;
}

int32
_ctc_at_dkit_misc_serdes_rx_prbs_stop(ctc_at_dkit_serdes_dev_t* p_dev)
{
    uint16 serdes_id = 0;
    ctc_dkit_monitor_task_t* p_mon_task = &(g_usw_dkit_master[p_dev->lchip]->monitor_task[CTC_DKIT_MONITOR_TASK_PRBS_BER]);
    ctc_dkit_at_serdes_ber_mon_t* p_ber_mon = NULL;
    
    _ctc_at_dkit_misc_serdes_opr_lock(p_dev->lchip, p_dev->serdes_id);
    /*1. stop thread*/
    _ctc_at_dkit_misc_serdes_ber_record_clear(p_dev->lchip, p_dev->serdes_id);

    if(p_mon_task->monitor_task)
    {
        p_ber_mon = (ctc_dkit_at_serdes_ber_mon_t*)p_mon_task->para;
        if(p_ber_mon && (0 == p_ber_mon->is_run))
        {
            p_mon_task->task_end = 1;
            sal_task_destroy(p_mon_task->monitor_task);
            p_mon_task->monitor_task = NULL;
            if(p_mon_task->para)
            {
                mem_free(p_mon_task->para);
                p_mon_task->para = NULL;
            }
        }
    }
    /*2. disable prbs rx*/
    _ctc_at_dkit_set_prbs_en(p_dev, DKIT_AT_DIR_RX, 0);
    
    _ctc_at_dkit_misc_serdes_opr_unlock(p_dev->lchip, p_dev->serdes_id);

    _ctc_at_dkit_serdes_psd_to_serdes(p_dev->lchip, p_dev->serdes_id, &serdes_id);
    CTC_DKIT_PRINT("Serdes %u PRBS test stop\n", serdes_id);

    return CLI_SUCCESS;
}

int32
_ctc_at_dkit_misc_serdes_rx_prbs_clear(ctc_at_dkit_serdes_dev_t* p_dev)
{
    uint16 serdes_id = 0;
    _ctc_at_dkit_misc_serdes_opr_lock(p_dev->lchip, p_dev->serdes_id);
    /*1. stop and clear thread buf*/
    _ctc_at_dkit_misc_serdes_ber_record_clear(p_dev->lchip, p_dev->serdes_id);
    /*2. clear register stat*/
    _ctc_at_dkit_reset_comparator_stats(p_dev);
    /*3. rerun thread*/
    _ctc_at_dkit_misc_serdes_ber_record_start(p_dev->lchip, p_dev->serdes_id);
    
    _ctc_at_dkit_misc_serdes_opr_unlock(p_dev->lchip, p_dev->serdes_id);

    _ctc_at_dkit_serdes_psd_to_serdes(p_dev->lchip, p_dev->serdes_id, &serdes_id);
    CTC_DKIT_PRINT("Serdes %u PRBS test clear statistics\n", serdes_id);

    return CLI_SUCCESS;
}

int32
_ctc_at_dkit_misc_serdes_rx_prbs_print(ctc_at_dkit_serdes_dev_t* p_dev)
{
    uint64 errcnt = 0;
    uint64 totcnt = 0;
    uint8 tx_speed = 0;
    uint8 rx_speed = 0;
    uint16 serdes_id = 0;
    uint32 cli_pattern = 0;
#ifdef CTC_MATH_FLOATING
    /*double ber = 0;*/
    uint64 ber_v = 0;
    uint64 ber_e = 0;
#endif
    ctc_dkit_monitor_task_t* p_mon_task = &(g_usw_dkit_master[p_dev->lchip]->monitor_task[CTC_DKIT_MONITOR_TASK_PRBS_BER]);
    _dkit_at_serdes_pattern_stats_t prbs_stats;
    ctc_dkit_at_serdes_ber_mon_t* p_ber_mon = NULL;
    char* pattern[] = {"PRBS7", "PRBS7", "PRBS15", "PRBS15", "PRBS23", "PRBS23", "PRBS31", "PRBS31", "PRBS9", "Squareware(8081)", "PRBS11", "PRBS1T(1010)",
                        "PRBS13", "PRBS9", "PRBS13", "PRBS15", "PRBS31", "PRBS9", "PRBS13", "PRBS15", "PRBS31"};
    char* lane_rate[] = {
        "0G       ", "1.25G    ", "3.125G   ", "10.3125G ",
        "11.40625G", "12.5G    ", "12.96875G", "10.9375G ", "20.625G",
        "25.78125G", "28.125G  ", "26.5625G ", "27.34375G",
        "27.78125G", "37.5G    ", "39.0625G ", "51.5625G ",
        "53.125G  ", "56.25G   ", "103.125G ", "106.25G  ", "112.5G   ", "42.5G"
    };

    _ctc_at_dkit_misc_serdes_opr_lock(p_dev->lchip, p_dev->serdes_id);

    _ctc_at_dkit_serdes_psd_to_serdes(p_dev->lchip, p_dev->serdes_id, &serdes_id);
    p_ber_mon = (ctc_dkit_at_serdes_ber_mon_t*)p_mon_task->para;
    if(NULL == p_ber_mon)
    {
        CTC_DKIT_PRINT("Serdes %u test is over. Why not print result before stop?\n", serdes_id);
        _ctc_at_dkit_misc_serdes_opr_unlock(p_dev->lchip, p_dev->serdes_id);
        return CLI_SUCCESS;
    }

    /* 1. get current count */
    _ctc_at_dkit_get_comparator_stats(p_dev, &prbs_stats);
    _ctc_at_dkit_reset_comparator_stats(p_dev);
    p_ber_mon->err_cnt[p_dev->serdes_id] += prbs_stats.totalErrorBits;
    p_ber_mon->tot_cnt[p_dev->serdes_id] += prbs_stats.totalBits;
    errcnt = p_ber_mon->err_cnt[p_dev->serdes_id];
    totcnt = p_ber_mon->tot_cnt[p_dev->serdes_id];

    _ctc_at_dkit_get_txrx_rate(p_dev, &tx_speed, &rx_speed);
    tx_speed = _ctc_at_dkit_serdes_get_related_serdes_speed(tx_speed, p_dev->type);
    rx_speed = _ctc_at_dkit_serdes_get_related_serdes_speed(rx_speed, p_dev->type);
    _ctc_at_dkit_get_prbs_pattern(p_dev, DKIT_AT_DIR_RX, &cli_pattern);
    
    CTC_DKIT_PRINT("\n%-12s%-6s%-10s%-10s%-16s %-16s%-9s\n", "Serdes_ID", "Dir", "LaneRate", "Pattern", "Total_cnt", "Err_cnt", "BER");
    CTC_DKIT_PRINT("-------------------------------------------------------------------------------\n");

#ifdef CTC_MATH_FLOATING
    if((errcnt == 0) && (totcnt != 0))
    {
#ifdef UINT64_PRINT_FMT_LU
        CTC_DKIT_PRINT("%-12d%-6s%-10s%-10s%-16lu %-16lu%-9s\n", 
            serdes_id, "RX", lane_rate[rx_speed], pattern[cli_pattern], totcnt, errcnt, "FREE");
#else
        CTC_DKIT_PRINT("%-12d%-6s%-10s%-10s%-16ju %-16ju%-9s\n", 
            serdes_id, "RX", lane_rate[rx_speed], pattern[cli_pattern], totcnt, errcnt, "FREE");
#endif
    }
    else if(totcnt == 0)
    {
#ifdef UINT64_PRINT_FMT_LU
        CTC_DKIT_PRINT("%-12d%-6s%-10s%-10s%-16lu %-16lu%-9s\n", 
            serdes_id, "RX", lane_rate[rx_speed], pattern[cli_pattern], totcnt, errcnt, "--");
#else
        CTC_DKIT_PRINT("%-12d%-6s%-10s%-10s%-16ju %-16ju%-9s\n", 
            serdes_id, "RX", lane_rate[rx_speed], pattern[cli_pattern], totcnt, errcnt, "--");
#endif
    }
    else
    {
#ifdef UINT64_PRINT_FMT_LU
        /*ber = ((double)errcnt) / ((double)totcnt);*/
        /*CTC_DKIT_PRINT("%-12d%-6s%-10s%-10s%-16lu %-16lu%-9.3e\n", 
            p_dev->serdes_id, "RX", lane_rate[rx_speed], pattern[cli_pattern], totcnt, errcnt, ber);*/
        _ctc_at_dkit_misc_get_div_exp10(errcnt, totcnt, 2, &ber_v, &ber_e);
        CTC_DKIT_PRINT("%-12d%-6s%-10s%-10s%-16lu %-16lu%lu.%02lue-%lu\n", 
            serdes_id, "RX", lane_rate[rx_speed], pattern[cli_pattern], totcnt, errcnt, ber_v/100, ber_v%100, ber_e);
#else
        /*ber = ((double)errcnt) / ((double)totcnt);*/
        /*CTC_DKIT_PRINT("%-12d%-6s%-10s%-10s%-16ju %-16ju%-9.3e\n", 
            p_dev->serdes_id, "RX", lane_rate[rx_speed], pattern[cli_pattern], totcnt, errcnt, ber);*/
        _ctc_at_dkit_misc_get_div_exp10(errcnt, totcnt, 2, &ber_v, &ber_e);
        CTC_DKIT_PRINT("%-12d%-6s%-10s%-10s%-16ju %-16ju%ju.%02jue-%ju\n", 
            serdes_id, "RX", lane_rate[rx_speed], pattern[cli_pattern], totcnt, errcnt, ber_v/100, ber_v%100, ber_e);
#endif
    }
#else
#ifdef UINT64_PRINT_FMT_LU
    CTC_DKIT_PRINT("%-12d%-6s%-10s%-10s%-16lu %-16lu%-9s\n", 
        serdes_id, "RX", lane_rate[rx_speed], pattern[cli_pattern], totcnt, errcnt, "--");
#else
    CTC_DKIT_PRINT("%-12d%-6s%-10s%-10s%-16ju %-16ju%-9s\n", 
        serdes_id, "RX", lane_rate[rx_speed], pattern[cli_pattern], totcnt, errcnt, "--");
#endif
#endif

    _ctc_at_dkit_misc_serdes_opr_unlock(p_dev->lchip, p_dev->serdes_id);

    return CLI_SUCCESS;
}

/*0-stop 1-run 2-clear 3-print*/
void
_ctc_at_dkit_misc_serdes_rx_prbs_batch(uint8 lchip, uint32 menu, uint32 pattern, uint32 bmp_len, uint32 serdes_bmp[])
{
    uint16 i, j;
    ctc_at_dkit_serdes_dev_t dev;

    dev.lchip = lchip;

    switch(menu)
    {
        case 0: /*stop*/
            for(i = 0; i < bmp_len; i++)
            {
                for(j = 0; j < 32; j++)
                {
                    if(((serdes_bmp[i] >> j) & 0x1) != 0)
                    {
                        (void)_ctc_at_dkit_serdes_serdes_to_psd(lchip, (32 * i + j), &(dev.serdes_id));
                        dev.type = _ctc_at_dkit_get_serdes_type(lchip, dev.serdes_id);
                        (void)_ctc_at_dkit_misc_serdes_rx_prbs_stop(&dev);
                    }
                }
            }
            break;
        case 1: /*run*/
            for(i = 0; i < bmp_len; i++)
            {
                for(j = 0; j < 32; j++)
                {
                    if(((serdes_bmp[i] >> j) & 0x1) != 0)
                    {
                        (void)_ctc_at_dkit_serdes_serdes_to_psd(lchip, (32 * i + j), &(dev.serdes_id));
                        dev.type = _ctc_at_dkit_get_serdes_type(lchip, dev.serdes_id);
                        (void)_ctc_at_dkit_misc_serdes_rx_prbs_run(&dev, pattern);
                    }
                }
            }
            break;
        case 2: /*clear*/
            for(i = 0; i < bmp_len; i++)
            {
                for(j = 0; j < 32; j++)
                {
                    if(((serdes_bmp[i] >> j) & 0x1) != 0)
                    {
                        (void)_ctc_at_dkit_serdes_serdes_to_psd(lchip, (32 * i + j), &(dev.serdes_id));
                        dev.type = _ctc_at_dkit_get_serdes_type(lchip, dev.serdes_id);
                        (void)_ctc_at_dkit_misc_serdes_rx_prbs_clear(&dev);
                    }
                }
            }
            break;
        case 3: /*print*/
        default:
            for(i = 0; i < bmp_len; i++)
            {
                for(j = 0; j < 32; j++)
                {
                    if(((serdes_bmp[i] >> j) & 0x1) != 0)
                    {
                        (void)_ctc_at_dkit_serdes_serdes_to_psd(lchip, (32 * i + j), &(dev.serdes_id));
                        dev.type = _ctc_at_dkit_get_serdes_type(lchip, dev.serdes_id);
                        (void)_ctc_at_dkit_misc_serdes_rx_prbs_print(&dev);
                    }
                }
            }
            break;
    }
}

/* arctic diag param description

    mode 0  : serdes reset op
        param[1]: 
            0: txrx reset    (clear state machine, keep configure)
            1: global reset  (clear both state machine & configure)
            2: pram reset    (reset pram, dont clear content)
            3: power ivref   (hardware poweroff, need reinitialize)
        param[2]: 
            0 : unreset 
            1 : reset  
    mode 1  : operate on macpcs intr
        param[1]:   
            0:  clear   intr
            1:  mask    intr
            2:  unmask  intr
            3:  read    intr
    mode 2  : MCU CMD
        param[1]:
            cmd_0to7
        param[2]:
            cmd_8to15
        param[3]:
            cmd_16to23
        param[4]:
            cmd_24to31
        param[5]:
            input data of the corresponding command
    mode 3  : print MCU CMD guide
        no input param
    mode 4  : serdes speed change simplify flow
        param[1]:
            new speed, refer to _ctc_at_dkit_serdes_speed_e
    mode 5  : SQ THRD set/get
        param[1]:
            0x00000000~0x0000ffff: set SQ THRD param[1]
            0x0000ffff~0xffffffff: get current SQ THRD
    mode 6  : TX error inject
        param[1]:
            1~8: error number 0~7
    mode 7  : TX error inject
        param[1]:
            1~8: error number 0~7
    mode 8  : TX error inject
        param[1]:
            1~8: error number 0~7
*/
int32
ctc_at_dkit_misc_serdes_diag(uint8 lchip, void* para)
{
    uint32 diag_id = 0;
    uint16 serdes_id = 0;
    uint16 psd = 0;
    uint16 val16 = 0;
    uint32 val32 = 0;
    uint32 val32_1 = 0;
    ctc_dkit_serdes_diag_para_t* p_para = (ctc_dkit_serdes_diag_para_t*)para;
    ctc_at_dkit_serdes_dev_t dev;

    if((p_para->param_cnt > 63) || (p_para->param_cnt == 0) || (p_para->p_param == NULL))
    {
        CTC_DKIT_PRINT("Invalid param number!\n");
        return CLI_EOL;
    }
    
    serdes_id = (uint16)(p_para->serdes_id);
    diag_id = p_para->p_param[0];

    /*DKITS_SERDES_ID_CHECK(lchip,serdes_id);*/

    (void)_ctc_at_dkit_serdes_serdes_to_psd(lchip, serdes_id, &psd);    
    _ctc_at_dkit_serdes_dev(lchip, psd, &dev);

    switch(diag_id)
    {
        case 0:
            if(3 != p_para->param_cnt)
            {
                CTC_DKIT_PRINT("serdes_reset: Input param number illegal, gaving %u expecting 2.\n", p_para->param_cnt-1);
                return CLI_SUCCESS;
            }
            _ctc_at_dkit_serdes_reset(&dev, (uint8)p_para->p_param[1], (uint16)p_para->p_param[2]);
            break;
        case 1:
            if(2 != p_para->param_cnt)
            {
                CTC_DKIT_PRINT("serdes_reset: Input param number illegal, gaving %u expecting 1.\n", p_para->param_cnt-1);
                return CLI_SUCCESS;
            }
            ctc_at_dkit_macpcs_abnormal_interrupt(lchip, (uint8)p_para->p_param[1]);
            break;
        case 2:
            if(6 != p_para->param_cnt)
            {
                CTC_DKIT_PRINT("serdes_reset: Input param number illegal, gaving %u expecting 5.\n", p_para->param_cnt-1);
                return CLI_SUCCESS;
            }
            _ctc_at_dkit_misc_serdes_mcu_cmd(&dev, (uint8)p_para->p_param[1], (uint8)p_para->p_param[2], 
                (uint8)p_para->p_param[3], (uint8)p_para->p_param[4], p_para->p_param[5]);
            break;
        case 3:
            if(1 != p_para->param_cnt)
            {
                CTC_DKIT_PRINT("serdes_reset: Input param number illegal, gaving %u expecting 0.\n", p_para->param_cnt-1);
                return CLI_SUCCESS;
            }
            _ctc_at_dkit_misc_serdes_print_mcu_cmd_guide();
            break;
        case 4:
            if(2 != p_para->param_cnt)
            {
                CTC_DKIT_PRINT("serdes_reset: Input param number illegal, gaving %u expecting 1.\n", p_para->param_cnt-1);
                return CLI_SUCCESS;
            }
            _ctc_at_dkit_speed_switch_simplify(lchip, psd, (uint8)p_para->p_param[1]);
            break;
        case 5:
            if(2 != p_para->param_cnt)
            {
                CTC_DKIT_PRINT("serdes_reset: Input param number illegal, gaving %u expecting 1.\n", p_para->param_cnt-1);
                return CLI_SUCCESS;
            }
            _ctc_at_dkit_get_sq_thrd(&dev, &val16);
            CTC_DKIT_PRINT("Current SQ Thrd: %u\n", val16);
            if(0x0000ffff >= p_para->p_param[1])
            {
                _ctc_at_dkit_set_sq_thrd(&dev, (uint16)p_para->p_param[1]);
                _ctc_at_dkit_get_sq_thrd(&dev, &val16);
                CTC_DKIT_PRINT("New SQ Thrd: %u\n", val16);
            }
            break;
        case 6:
            if(2 != p_para->param_cnt)
            {
                CTC_DKIT_PRINT("serdes_reset: Input param number illegal, gaving %u expecting 1.\n", p_para->param_cnt-1);
                return CLI_SUCCESS;
            }
            _ctc_at_dkit_misc_serdes_tx_err_inj(&dev, (uint8)p_para->p_param[1]);
            break;
        case 7:
            if(1 != p_para->param_cnt)
            {
                CTC_DKIT_PRINT("serdes_reset: Input param number illegal, gaving %u expecting 0.\n", p_para->param_cnt-1);
                return CLI_SUCCESS;
            }
            _ctc_at_dkit_misc_serdes_abnormal_intr_clear(lchip, psd);
            break;
        case 8:
            if(1 != p_para->param_cnt)
            {
                CTC_DKIT_PRINT("serdes_reset: Input param number illegal, gaving %u expecting 0.\n", p_para->param_cnt-1);
                return CLI_SUCCESS;
            }
            _ctc_at_dkit_misc_serdes_abnormal_intr_test(lchip, psd);
            break;
        case 9:
            if(1 != p_para->param_cnt)
            {
                CTC_DKIT_PRINT("serdes_reset: Input param number illegal, gaving %u expecting 0.\n", p_para->param_cnt-1);
                return CLI_SUCCESS;
            }
            _ctc_at_dkit_get_snr(&dev, &val32, &val32_1);
            CTC_DKIT_PRINT("SNR = %u (%u)\n", val32, val32_1);
            break;
        case 10:
            if(1 != p_para->param_cnt)
            {
                CTC_DKIT_PRINT("serdes_reset: Input param number illegal, gaving %u expecting 0.\n", p_para->param_cnt-1);
                return CLI_SUCCESS;
            }
            _ctc_at_dkit_56g_get_trained_eye_height(&dev);
            break;
        case 11:
            if(3 != p_para->param_cnt)
            {
                CTC_DKIT_PRINT("serdes_reset: Input param number illegal, gaving %u expecting 2.\n", p_para->param_cnt-1);
                return CLI_SUCCESS;
            }
            _ctc_at_dkit_set_precode(&dev, (uint8)p_para->p_param[1], (uint8)p_para->p_param[2]);
            break;
        case 12:
            if(3 != p_para->param_cnt)
            {
                CTC_DKIT_PRINT("serdes_reset: Input param number illegal, gaving %u expecting 2.\n", p_para->param_cnt-1);
                return CLI_SUCCESS;
            }
            _ctc_at_dkit_set_graycode(&dev, (uint8)p_para->p_param[1], (uint8)p_para->p_param[2]);
            break;
        case 13:
            _ctc_at_dkit_misc_serdes_rx_prbs_batch(lchip, p_para->p_param[1], p_para->p_param[2], p_para->p_param[3], &(p_para->p_param[4]));
            break;
        default:
            break;
    }
    
    return CLI_SUCCESS;
}


void *
_ctc_at_dkit_misc_serdes_ctl_param_convert(ctc_dkit_serdes_ctl_para_t *p_para)
{
    ctc_dkit_at_serdes_ctl_loopback_t  *loopback_param = NULL;
    ctc_dkit_at_serdes_ctl_prbs_t      *prbs_param = NULL;
    
    ctc_dkit_at_serdes_ctl_eye_t       *eye_param = NULL;
    /*
    ctc_dkit_at_serdes_ctl_ffe_t       *ffe_param = NULL;
    ctc_dkit_tmm_serdes_ctl_pol_check_t  *pol_check_param = NULL;
    ctc_dkit_tmm_serdes_ctl_dfe_t       *dfe_param = NULL;
    ctc_dkit_tmm_serdes_ctl_fw_t        *fw_param = NULL;
    */
    //ctc_dkit_tmm_serdes_ctl_bathtub_t   *bathtub_param = NULL;
    void *p_data = NULL;
    
        switch (p_para->type)
        {
            case CTC_DKIT_SERDIS_CTL_LOOPBACK:
                loopback_param = (ctc_dkit_at_serdes_ctl_loopback_t*)mem_malloc(MEM_CLI_MODULE, sizeof(ctc_dkit_at_serdes_ctl_loopback_t));
                if (NULL == loopback_param)
                {
                    break;
                }
                sal_memset(loopback_param, 0, sizeof(ctc_dkit_at_serdes_ctl_loopback_t));
                (void)_ctc_at_dkit_serdes_serdes_to_psd(p_para->lchip, p_para->serdes_id, &loopback_param->serdes_id);
                loopback_param->oper = p_para->para[0];
                loopback_param->mode = p_para->para[1];
                p_data = loopback_param;
                break;
            case CTC_DKIT_SERDIS_CTL_PRBS:
                prbs_param = (ctc_dkit_at_serdes_ctl_prbs_t*)mem_malloc(MEM_CLI_MODULE, sizeof(ctc_dkit_at_serdes_ctl_prbs_t));
                if (NULL == prbs_param)
                {
                    break;
                }
                sal_memset(prbs_param, 0, sizeof(ctc_dkit_at_serdes_ctl_prbs_t));
                prbs_param->lchip = p_para->lchip;
                (void)_ctc_at_dkit_serdes_serdes_to_psd(p_para->lchip, p_para->serdes_id, &prbs_param->serdes_id);
                prbs_param->oper = p_para->para[0];
                prbs_param->pattern = p_para->para[1];
                prbs_param->is_keep = p_para->para[2];
                prbs_param->timer_ms = p_para->para[3];
                prbs_param->errcnt = p_para->para[4];
                prbs_param->str = p_para->str;
                p_data = prbs_param;
                break;
                
            case CTC_DKIT_SERDIS_CTL_EYE:
                eye_param = (ctc_dkit_at_serdes_ctl_eye_t*)mem_malloc(MEM_CLI_MODULE, sizeof(ctc_dkit_at_serdes_ctl_eye_t));
                if (NULL == eye_param)
                {
                    break;
                }
                sal_memset(eye_param, 0, sizeof(ctc_dkit_at_serdes_ctl_eye_t));
                (void)_ctc_at_dkit_serdes_serdes_to_psd(p_para->lchip, p_para->serdes_id, &eye_param->serdes_id);
                eye_param->eye_type = p_para->para[0];
                eye_param->read_times = p_para->para[1];
                p_data = eye_param;
                break;
            /*
            case CTC_DKIT_SERDIS_CTL_FFE:
                ffe_param = (ctc_dkit_at_serdes_ctl_ffe_t*)mem_malloc(MEM_CLI_MODULE, sizeof(ctc_dkit_at_serdes_ctl_ffe_t));
                if (NULL == ffe_param)
                {
                    break;
                }
                sal_memset(ffe_param, 0, sizeof(ctc_dkit_at_serdes_ctl_ffe_t));
                ffe_param->serdes_id = p_para->serdes_id;
                ffe_param->dest_serdes_id = p_para->para[0];
                ffe_param->prbs_pattern = p_para->para[1];
                ffe_param->threshold = p_para->para[2];
                ffe_param->delay = p_para->para[3];
                ffe_param->str = p_para->str;
                ffe_param->ffe = &p_para->ffe;
                p_data = ffe_param;
                break;
            
            case CTC_DKIT_SERDIS_CTL_STATUS:
            case CTC_DKIT_SERDIS_CTL_ISI:
            case CTC_DKIT_SERDIS_CTL_DELAT_PH:
                break;
            case CTC_DKIT_SERDIS_CTL_POLR_CHECK:
                pol_check_param = (ctc_dkit_tmm_serdes_ctl_pol_check_t*)mem_malloc(MEM_CLI_MODULE, sizeof(ctc_dkit_tmm_serdes_ctl_pol_check_t));
                if (NULL == pol_check_param)
                {
                    break;
                }
                sal_memset(pol_check_param, 0, sizeof(ctc_dkit_tmm_serdes_ctl_pol_check_t));
                pol_check_param->serdes_id = p_para->serdes_id;
                pol_check_param->paired_serdes_id = p_para->para[0];
                p_data = eye_param;
                break;
            case CTC_DKIT_SERDIS_CTL_DFE:
            case CTC_DKIT_SERDIS_CTL_GET_DFE:
                dfe_param = (ctc_dkit_tmm_serdes_ctl_dfe_t*)mem_malloc(MEM_CLI_MODULE, sizeof(ctc_dkit_tmm_serdes_ctl_dfe_t));
                if (NULL == dfe_param)
                {
                    break;
                }
                sal_memset(dfe_param, 0, sizeof(ctc_dkit_tmm_serdes_ctl_dfe_t));
                dfe_param->serdes_id = p_para->serdes_id;
                dfe_param->oper = p_para->para[0];
                dfe_param->taps[0] = (uint8)(p_para->para[1] & 0xff);
                dfe_param->taps[1] = (uint8)(p_para->para[1] & (0xff << 8));
                dfe_param->taps[2] = (uint8)(p_para->para[1] & (0xff << 16));
                dfe_param->taps[3] = (uint8)(p_para->para[1] & (0xff << 24));
                dfe_param->taps[4] = (uint8)(p_para->para[2] & 0xff);
                p_data = dfe_param;
                break;
            case CTC_DKIT_SERDIS_CTL_FW:
                fw_param = (ctc_dkit_tmm_serdes_ctl_fw_t*)mem_malloc(MEM_CLI_MODULE, sizeof(ctc_dkit_tmm_serdes_ctl_fw_t));
                if (NULL == fw_param)
                {
                    break;
                }
                sal_memset(fw_param, 0, sizeof(ctc_dkit_tmm_serdes_ctl_fw_t));
                fw_param->serdes_id = p_para->serdes_id;
                fw_param->oper = p_para->para[0];
                p_data = fw_param;
                break;
            case CTC_DKIT_SERDIS_CTL_BATHTUB:
                bathtub_param = (ctc_dkit_tmm_serdes_ctl_bathtub_t*)mem_malloc(MEM_CLI_MODULE, sizeof(ctc_dkit_tmm_serdes_ctl_bathtub_t));
                if (NULL == bathtub_param)
                {
                    break;
                }
                sal_memset(bathtub_param, 0, sizeof(ctc_dkit_tmm_serdes_ctl_bathtub_t));
                bathtub_param->serdes_id = p_para->serdes_id;
                bathtub_param->oper = p_para->para[0];
                bathtub_param->depth = p_para->para[1];
                p_data = bathtub_param;
                break;
                */
            default:
                break;
        }
        
        return p_data;
    }


int32
ctc_at_dkit_misc_serdes_ctl(void* p_para)
{
    uint8 lchip;
    ctc_dkit_serdes_ctl_para_t* p_serdes_para = (ctc_dkit_serdes_ctl_para_t*)p_para;
    void *p_param = NULL;

    DKITS_PTR_VALID_CHECK(p_serdes_para);
    lchip = p_serdes_para->lchip;
    CTC_DKIT_LCHIP_CHECK(lchip);
    DRV_INIT_CHECK(lchip);

    p_param = _ctc_at_dkit_misc_serdes_ctl_param_convert(p_serdes_para);
    

    #if 0
    if((CTC_DKIT_SERDIS_CTL_STATUS != p_serdes_para->type) && (CTC_DKIT_SERDIS_CTL_ISI != p_serdes_para->type) &&  \
        (CTC_DKIT_SERDIS_CTL_DELAT_PH != p_serdes_para->type))
    {
        DKITS_PTR_VALID_CHECK(p_param);
    }
    #endif
    
    switch (p_serdes_para->type)
    {
        case CTC_DKIT_SERDIS_CTL_PRBS:
            _ctc_at_dkit_misc_serdes_prbs(lchip, p_param);
            break;
        case CTC_DKIT_SERDIS_CTL_LOOPBACK:
            _ctc_at_dkit_misc_serdes_loopback(lchip, p_param);
            break;
        case CTC_DKIT_SERDIS_CTL_EYE:
            _ctc_at_dkit_misc_serdes_eye(lchip, p_param);
            break;
        /*
        case CTC_DKIT_SERDIS_CTL_FFE:
            _ctc_tmm_dkit_misc_serdes_ffe_scan(lchip, p_param);
            break;
        case CTC_DKIT_SERDIS_CTL_STATUS:
            _ctc_tmm_dkit_misc_serdes_status(lchip, p_serdes_para->serdes_id, NULL);
            break;
        case CTC_DKIT_SERDIS_CTL_POLR_CHECK:
            _ctc_tmm_dkit_misc_serdes_polr_check(lchip, p_param);
            break;
        case CTC_DKIT_SERDIS_CTL_DFE:
            _ctc_tmm_dkit_misc_serdes_dfe_set_en(lchip, p_param);
            break;
            
        case CTC_DKIT_SERDIS_CTL_GET_DFE:
            _ctc_tmm_dkit_misc_serdes_show_dfe(lchip, p_param);  //use chip customization show format
            p_serdes_para->para[4] = 1;
            break;
        case CTC_DKIT_SERDIS_CTL_FW:
            _ctc_tmm_dkit_misc_serdes_fw(lchip, p_param);
            break;
        case CTC_DKIT_SERDIS_CTL_ISI:
            _ctc_tmm_dkit_misc_serdes_dump_ISI(lchip, p_serdes_para->serdes_id, NULL);
            break;
        case CTC_DKIT_SERDIS_CTL_DELAT_PH:
            _ctc_tmm_dkit_misc_serdes_get_delta_ph(lchip, p_serdes_para->serdes_id);
            break;
        case CTC_DKIT_SERDIS_CTL_BATHTUB:
            ctc_tmm_dkit_misc_serdes_do_bathtub(lchip, p_param);
            break;
        default:
            break;*/
            
        default:
            break;
    }

    mem_free(p_param);
    
    return CLI_SUCCESS;
}
